二分查找 704

题目:力扣704

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

解法1:左闭右闭 [left, right] 

注意如下两点:

  • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
class Solution {public int search(int[] nums, int target) {if(nums.length==0||target>nums[nums.length-1])return -1;int left=0;int right=nums.length-1;while(left<=right){int mid =left+(right-left)/2;if(nums[mid]>target){right=mid-1;}else if(nums[mid]

left + ((right -left) >> 1) == (left + right) /2

>>: 二进制右移
举个例子: 1010 >> 1 == 0101
1010 十进制 10
0101 十进制 5
综上 >> 1 作用相当于除二

所以 left + ((right -left) >> 1) ==> left + ((right -left)/2)
==> left + right/2 -left/2 ==> left/2 + right/2 ==> (left + right) /2

为什么不直接用(left + right) /2 而用left + ((right -left) >> 1)
答: 是因为left + right 在某种情况下可能会超过基本类型所能容纳的最大值,而且 >> (位运算) 比 / 运算要快一点
 

解法2:左闭右开 [left, right)

注意如下两点:

  • while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
  • if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]
class Solution {public int search(int[] nums, int target) {if(nums.length==0||target>nums[nums.length-1])return -1;int left=0;int right=nums.length;while(lefttarget){right=mid;}else if(nums[mid]


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章