秋招突击——7/10——复习{}——新作{在排序数组中查找元素的第一个最后一个位置、搜索旋转排序数组}

news2025/4/21 21:25:16

文章目录

    • 引言
    • 复习
    • 新作
      • 在排序数组中查找元素的第一个和最后一个位置
        • 个人实现
        • 参考实现
      • 搜索旋转排序数组
        • 个人实现
        • 参考实现
    • 总结

引言

复习

新作

在排序数组中查找元素的第一个和最后一个位置

题目链接

在这里插入图片描述
注意

  • 非递减序列==》元素是递增或者相等,并不是严格递增的
  • 找到给定目标值在数组中开始的位置和结束的位置
  • 时间复杂度是logn
个人实现
  • 这道题就是典型的二分查找的,但是需要知道你背的模板的特点的——“左加大,右减小”
class Solution {
    public int[] searchRange(int[] nums, int tar) {
        
        //define result vector
        int[] res = {-1,-1};

        if(nums.length == 0)    return res;

        
        // binary find
        int m = nums.length;
        int l = 0,r = m - 1;
        while(l < r){
            int mid = (l + r) >> 1;
            if(nums[mid] >= tar) r = mid;
            else l = mid + 1;
        }
        // System.out.println(l);
        // judge whether find the value
        if(nums[l] != tar)   return res;
        
        // the value is the first bigger num
        while(l >= 1 && nums[l - 1] == tar)  l --;
        while(r + 1 < m && nums[r + 1] == tar)  r++;
        res[0] = l;
        res[1] = r;
        return res;
    }
}
  • 写是写完了,这里得去看一下Java中数组的操作,这里整的有点不熟悉,导致很多操作和C++弄混了!
// create the fixed length array
int[] fixedArray = new int[5];
int[] ifxedArray = {1,2,3,4,5};
参考实现
  • 这里是使用了两个不同的模板,一个确定左边界,还有一个是确定有边界的。具体两个模板如下

确定左边界

int l = 0,r = m-1;
while(l < r){
	int mid = (r + l) >> 1;
	if(nums[mid] >= tar)	r = mid;
	else l = mid + 1;
}
// l is the left edge 

确定右边界

int l = 0,r = m - 1;
while(l < r){
	int mid = (l + r + 1) >> 1;  // 仅仅针对右边界,防止死循环
	if(nums[mid] <= tar)	l = mid;
	else r = mid - 1;
}

最终实现如下

class Solution {
    public int[] searchRange(int[] nums, int tar) {
        
        //define result vector
        int[] res = {-1,-1};
        if(nums.length == 0)    return res;
        
        // binary find
        int m = nums.length;
        int l = 0,r = m - 1;
        while(l < r){
            int mid = (l + r) >> 1;
            if(nums[mid] >= tar) r = mid;
            else l = mid + 1;
        }
        
        // judge whether find the value
        if(nums[l] != tar)   return res;
        res[0] = l;
        // the value is the first bigger num

        l = l ;
        r = m - 1;
        while(l < r){
            int mid = (l + r + 1) >> 1;
            System.out.println(mid);
            if(nums[mid] <= tar)    l = mid;
            else r = mid - 1;
        }
        res[1] = r;
        return res;
    }
}

搜索旋转排序数组

  • 题目链接
    在这里插入图片描述
    注意
  • 数组严格单调递增
  • 数组不为空
  • 数组的值不会存在溢出的情况
个人实现
  • 这道题是一个二分查找,但是需要转换坐标,将当前坐标转换为未旋转之前的坐标,或者是对其进行分段二分,然后查找目标值。
  • 现在有一个问题,无论是哪种方法,都需要知道在哪里进行的反转,如果完整遍历一次对应元素,时间复杂度就是O(n),肯定超时,现在就是想着通过单调递增的方式,尽量快速确定反转的地方。
  • 找到反转点
    • 元素与元素 之间只有严格的大于或者小于关系,往后遍历就是一定大于,往前遍历一定小于,异常就是说明旋转点,就在这一段
  • 找到target就是使用二分查找
class Solution {

    public int binFind(int[] nums,int l,int r,int tar){
        while(l < r){
            int mid = (l + r) >> 1;
            if(nums[mid] >= tar) r = mid;
            else  l = mid + 1;
        }
        return l;
    }
    public int search(int[] nums, int tar) {
        int m = nums.length ;
        // handle the edge situation
        if(m == 1)  return nums[0] == tar?0:-1;

        // find the reverse point
        int len = m / 2;
        int revP = 0;
        while(len > 1){
            if(nums[revP] < nums[revP + len - 1]){
                revP += len;
            }else{
                len /= 2;
            }
        }

        // find the target 
        int res;
        System.out.println(revP);
        if(tar > nums[0]){
            res = binFind(nums,0,revP,tar);
        }else{
            System.out.println("last");
                res = binFind(nums,revP + 1 ,m - 1,tar);
         
        }
        System.out.println(res);


        // judge the result 
        if(nums[res] == tar)    return res;
        else return -1;

    }
}

在这里插入图片描述
这里只能通过部分样例

  • 因为第一个是总是能够算准的,但是第二个不好处理,不应该呀!第二个总是越界,出现各种各样的问题!
    • 反转点在第一个元素的位置
    • 反转点在最后一个元素的位置
    • 仅有两个元素,如何进行判定

但是就是会出现异常!难受!

参考实现
  • 这里整体的思路和我的一样,先找划分点,然后二分查找。

这里有一个很巧妙的地方,就是一开始根据条件确定旋转点,类似的二分都可以用同样的思路

  • 基本想法和我的是一样的,都是通过等分对应区间长度,然后在进行比较划分,只不过他的套用模板,可靠性更高!

在这里插入图片描述

  • 具体实现代码如下
class Solution {

    
    public int search(int[] nums, int tar) {
        int m = nums.length ;
        // handle the edge situation
        if(m == 1)  return nums[0] == tar?0:-1;

        // find the reverse point
        int l = 0 ,r = m - 1;
        while(l < r){
            int mid = (l + r + 1) >> 1;
            if(nums[mid] >= nums[0]) l = mid;
            else  r = mid - 1;
        }

        // find the target 
        if(tar >= nums[0] ){
            l= 0;
        }else{
            l = l + 1;
            r = m - 1; 
        }


         while(l < r){
            int mid = (l + r) >> 1;
            if(nums[mid] >= tar) r = mid;
            else  l = mid + 1;
        }


        // judge the result 
        if(nums[r] == tar)    return r;
        else return -1;

    }
}

对于模板的进一步总结
左加大返回右,右减小返回左

// 方案一,右边界
int l = 0,r = m - 1;
while(l < r){
	int mid = (r+l)>>1;
	if(nums[mid] >= tar)	r = mid;
	else l = mid + 1;
}
return r;

// 方案二,左边界
int l = 0,r = m - 1;
while(l < r){
	int mid = (r+l)>>1;
	if(nums[mid] <= tar)	l = mid;
	else r = mid - 1;
}
return l;

总结

  • 昨天是纯纯摆烂了,主要是最近的状态属实不是很好,学不进去,昨晚上看了一会电视,聊了会天,看了会书,然后十二点就睡了,早上起来挺早的,背了会书,现在开始刷算法,进度还行,调整一下,效果还是很好的!
  • 投了字节的另外一个部门,然后居然还给我面试了,这周五,继续加油!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1917278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【GreenHills】GHS-Servecode的查看和说明

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 在Green Hills客户申请license试用以及正式文件的Servecode编号会有不同&#xff0c;该文档对此进行说明并如何主动查看Servecode&#xff0c;并且说明Servecode的类别&#xff0c;通过Servecode了解客户授权情况。 …

【机器学习】初学者经典案例(随记)

&#x1f388;边走、边悟&#x1f388;迟早会好 一、概念 机器学习是一种利用数据来改进模型性能的计算方法&#xff0c;属于人工智能的一个分支。它旨在让计算机系统通过经验自动改进&#xff0c;而不需要明确编程。 类型 监督学习&#xff1a;使用带标签的数据进行训练&…

慢性肾脏病-MR+转录组文献

Identification of novel therapeutic targets for chronic kidney disease and kidney function by integrating multi-omics proteome with transcriptome - PMC (nih.gov) 数据和材料 Our pQTL summary data were acquired from previously published studies and can be f…

const7配置静态网络连接

cd /etc/sysconfig/network-scripts/ //进入到network-scripts目录下 vi ifcfg-ens32 //编辑配置文件 修改文件内容 ps&#xff1a;因为我这里是NAT模式下的网络 子网掩码和网关就使用这里默认的 ip设置请取除子网ip 192.168.149.0 和网关192.168.149.2之外的&#xff08…

AI普及时代即将来临,我们如何提升自我竞争力?

自ChatGPT发布以来&#xff0c;形形色色的AI工具形同雨后春笋&#xff0c;令人眼花缭乱&#xff0c;不知所措。 许多听说过AI的人&#xff0c;或者使用过AI工具&#xff0c;如 文心一言&#xff0c;通义千问&#xff0c;ChatGPT等等也只会提一些简单的问题。那么&#xff0c;面…

Linux的tmp目录占用空间100%问题分析和解决

一、背景 系统运行期间&#xff0c;客户突然反馈上传文档传不上去。研发立马排查日志&#xff0c;发现日志中出现大量的“No space avaliable on disk”&#xff0c;下意识应用服务器磁盘满了&#xff0c;赶快连上服务器查看磁盘空间占用情况&#xff1a; 黑人问号脸&#xff…

LLM-文本分块(langchain)与向量化(阿里云DashVector)存储,嵌入LLM实践

文章目录 前言向量、令牌、嵌入分块按字符拆分按字符递归拆分按token拆分 向量化使用 TextEmbedding 实现语义搜索数据准备通过 DashScope 生成 Embedding 向量通过 DashVector 构建检索&#xff1a;向量入库语义检索&#xff1a;向量查询完整代码 总结 前言 Transformer 架构…

前端使用Vue和Element实现可拖动弹框效果,且不影响底层元素操作,Cesium作为底图(可拖拽的视频实时播放弹框,底层元素可以正常操作)

简述&#xff1a;在前端开发中&#xff0c;弹框和实时视频播放是常见的需求。这里来简单记录一下&#xff0c;如何使用Vue.js和Element UI实现一个可拖动的弹框&#xff0c;并在其中播放实时视频。同时&#xff0c;确保在拖拽弹框时&#xff0c;底层元素仍然可以操作。这里来记…

常用知识碎片 分页组件的使用(arco-design组件库)

目录 分页组件使用 API 组件代码示例 使用思路&#xff1a; 前端示例代码 html script 后端示例代码 Controller Impl xml 总结 分页组件使用 使用Arco Design之前需要配置好搭建前端环境可以看我另外一篇文章&#xff1a; 手把手教你 创建Vue项目并引入Arco Desi…

【JavaWeb程序设计】Servlet(二)

目录 一、改进上一篇博客Servlet&#xff08;一&#xff09;的第一题 1. 运行截图 2. 建表 3. 实体类 4. JSP页面 4.1 login.jsp 4.2 loginSuccess.jsp 4.3 loginFail.jsp 5. mybatis-config.xml 6. 工具类&#xff1a;创建SqlSessionFactory实例&#xff0c;进行 My…

十八.升职加薪系列-JVM垃圾回收器-开天辟地的ZGC

前言 随着Java的发展&#xff0c;JVM的GC垃圾回收器也在跟着升级&#xff0c;从早起的单线程垃圾回收器Serial&#xff0c;到多线程的垃圾回收器Parallel Scavenge&#xff0c;再到并发垃圾回收器CMS,G1等。它们在某些对延迟要求比较高的系统来说都有些力不从心,比如&#xff…

物联网系统中市电电量计量方案(一)

为什么要进行电量计量&#xff1f; 节约资源&#xff1a;电量计量可以帮助人们控制用电量&#xff0c;从而达到节约资源的目的。在当前严峻的资源供应形势下&#xff0c;节约能源是我们应该重视的问题。合理计费&#xff1a;电表可以帮助公共事业单位进行合理计费&#xff0c;…

R包:‘ggcharts好看线图包‘

介绍 ggcharts提供了一个高级{ggplot2}接口&#xff0c;用于创建通用图表。它的目标既简单又雄心勃勃:让您更快地从数据可视化的想法到实际的绘图。所以如何?通过处理大量的数据预处理&#xff0c;为您模糊{ggplot2}细节和绘图样式。生成的图是ggplot对象&#xff0c;可以使用…

物联网系统中市电电量计量方案(二)

上文我们主要介绍了电量计量中最重要的组成部分——电量计量芯片&#xff08;如果没有阅读该文章的&#xff0c;可以点击这里&#xff09;。本文会再为大家介绍电量计量的另外一个组成部分——电流互感器。 电流互感器的定义 电流互感器是一种可将一次侧大电流转换为二次侧小电…

Sentinel-1 Level 1数据处理的详细算法定义(三)

《Sentinel-1 Level 1数据处理的详细算法定义》文档定义和描述了Sentinel-1实现的Level 1处理算法和方程&#xff0c;以便生成Level 1产品。这些算法适用于Sentinel-1的Stripmap、Interferometric Wide-swath (IW)、Extra-wide-swath (EW)和Wave模式。 今天介绍的内容如下&…

室内精准定位哪个产品抗干扰能力强?可以用于哪些方面?

室内精准定位产品其实有很多&#xff0c;其实它是安装在室内接收型号的一个基站&#xff0c;并且范围有一定的限制&#xff0c;而被定位的人员需要携带定位产品&#xff0c;那么通过室内基站收集到的信息&#xff0c;将会通过专业的系统处理后呈现在相应的设备上&#xff0c;比…

Linux下常见压缩文件tar.xz、tar.bz2、tar.gz的区别和详解

文章目录 tar.xz tar.bz2 tar.gz 的区别三种文件的解压方式tar.xz的解压三种压缩文件的创建方式 tar.xz tar.bz2 tar.gz 的区别 这三个文件扩展名都表示压缩后的档案文件&#xff0c;但它们使用不同的压缩算法。 tar.xz: tar 代表 Tape Archive&#xff0c;它是一种将多个文件…

f_mkfs格式化最小分区数是191

使用fatfs的f_mkfs最小分区数是191原因&#xff1a; 在挂载ram_disk时参考的文章有提到&#xff1a; “然后是GET_SECTOR_COUNT 用于f_mkfs格式化时获取可用的sector的数量&#xff0c;32bit-LBA的情况下至少为191” 自己也实际试过确实要不少于191&#xff0c;网上也没找到相…

WMS系统的模块构成

WMS系统的模块构成通常包括以下几个主要部分&#xff1a; ———————————————————————————————— 1、库存管理&#xff1a; 主要负责管理仓库内的库存信息&#xff0c;包括库存记录、库存调整、库存盘点等功能。 2、入库管理&#xff1a; 负责处…

samba共享windows和ubuntu的文件

通过Samba服务器实现Windows与Ubuntu之间的文件共享是一个常见的需求&#xff0c;下面是实现这一目标的详细步骤&#xff1a; 一、Ubuntu开启Samba服务器 安装Samba&#xff1a; 打开终端&#xff0c;使用以下命令安装Samba服务&#xff1a; sudo apt update sudo apt install…