704.二分查找

news/2024/10/19 23:23:49

题目

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。示例 1:输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1提示:你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。

这道题写了两次

img

分析下第一次的代码:

class Solution {
public:int search(vector<int>& nums, int target) {int l = 0, r = nums.size() - 1;while (l < r){int mid = (l + r) >> 1;if (nums[mid] < target)l = mid + 1;else r = mid;}if (nums[l] == target)return l;return -1;}
};

第一次的执行时间不太理想,通过看别人的题解发现可以把if条件再细化点,如果找到了就直接退出函数,而不是等while条件不满足了才退出。

于是改进得到第二次写法:

class Solution {
public:int search(vector<int>& nums, int target) {int l = 0, r = nums.size() - 1;while (l < r){int mid = (l + r) >> 1;if (target > nums[mid]) l = mid + 1;else if (target == nums[mid]) return mid;else r = mid - 1;}if (nums[l] != target) return -1;return l;}
};

但是第二次写法其实还有改进空间,附上官方题解就知道为什么了:

class Solution {
public:int search(vector<int>& nums, int target) {int left = 0, right = nums.size() - 1;while(left <= right){int mid = (right - left) / 2 + left;int num = nums[mid];if (num == target) {return mid;} else if (num > target) {right = mid - 1;} else {left = mid + 1;}}return -1;}
};

主要是对return的处理上,其实如果不是在while循环里return,那么肯定没找到,所以在while循环外返回-1就行了。

还有就是在求mid上,官方写法避免了若left和right相加过大导致溢出的问题。

附上y总二分模板:二分查找算法模板

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

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

相关文章

win11微软拼音输入法变繁体字

0. 设置→时间和语言 1. 时间和语言→语言和区域2. 中文简体→语言选项3. 键盘→微软拼音→键盘选项4. 常规5. 选择字符集→简体中文

泰山学堂选拔游记

泰山学堂选拔游记 前言:由于相关保密协议,所有与选拔试题与详细细节有关的内容将被剔除。 Tips:由于神秘因素,我在中学阶段的各个平台部分文章与笔记已经进行了隐藏。 插曲:等通知大学的经典通知方式 通过笔试后,要加对应取向面试群了解消息,但各个取向过笔试预留加面试…

mongo基本命令(一)

一 前言 环境: win10 mongo6.0.1 记录一些基本的mongo查询命令 二 查询命令 1 进入命令行 进入mongo命令行,我这里是mongo是装在docker里面的 需要先在docker里面启动mongo容器 docker exec -it xxx bash 进入mongo容器,xxx为mongo容器名 mongosh 进入mongo命令行,我安装…

Java21虚拟线程:我的锁去哪儿了?

0 前言 最近的文章中,我们详细介绍了当我们迁移到 Java 21 并将代际 ZGC 作为默认垃圾收集器时,我们的工作负载是如何受益的。虚拟线程是我们在这次迁移中兴奋采用的另一个特性。 对虚拟线程新手,它们被描述为“轻量级线程,大大减少编写、维护和观察高吞吐量并发应用程序的…

ManualResetEventManualResetEventSlim

ManualResetEvent ManualResetEvent有三个重要的方法,分别为:waiteone(),set(),reset(),其含义如下: 1.WaitOne()即等待信号发出,即可往下运行。 2.set()发出信号,让线程方法继续往下运行,并允许其他线程(如有)一并往下运行。 3.reset()重新初始化(即:去掉票据)变为…

golang项目引用GitHub私有仓库module

1.创建go module项目module的名字假设为go-testmodule项目创建成功后,将go.mod文件中的 module "go-test" 修改成module "github.com/tonglin0325/go-test"避免引用的时候go get的时候报错,如下go get github.com/tonglin0325/go-test@latest go: github…

时序约束和综合+跨时钟产生的问题+spyglass的使用+SOC设计问题

时序约束和综合 时钟频率 # 时钟单位为ns,2ns对应500M时钟频率 create_clock -period 2 [get ports clk]skew # 设置时钟的skew,即上升沿之间的误差,当前设置为0.3ns set_clock_uncertainty -setup 0.3 [get_clocks CLK]transition # 设置时钟上升沿的转化时间 set_clock_tr…