Day 1 二分查找
如理解有误欢迎指正交流~
link:704. 二分查找 - 力扣(LeetCode)
思路分析
题目给出数组升序 ,想到二分查找(好吧其实题目也给出来了w)
找到mid,根据逻辑大小缩小范围比较.
全包围[lefg,right]
假如数组大小为6,取值范围就是[0,5].闭区间使得定义left = 0,right = nums.length-1(防止越界指针无效,也是根据此处可以反推没有左开右闭情况)
left指针是0.right是5,这个时候left == right是有效的,结束条件也就是left<=right,再根据mid位置进行判断,target是再mid左边还是右边或者是幸运的查找到目标位置.
class Solution {public int search(int[] nums, int target) {//看到数组习惯性反应越界问题//闭区间int right = nums.length - 1;int left = 0;while(left <= right) {int mid = left + (right - left) / 2;if(nums[mid] < target) {left = mid + 1;}else if(nums[mid] > target) {right = mid -1;}else {return mid;}}return -1;}
}
左闭右开[left,rigjht)
同样的条件但是right指针指向nums.length,对应的left == right没有意义.所以判断条件是left < right.如果target在nums[mid]左边的话,把left赋值为mid+1,但是反过来target在nums[mid]右边的话,就要赋值left为mid【右边开mid指的指针不参加下一次循环判读】
class Solution {public int search(int[] nums, int target) { int right = nums.length;int left = 0;while(left < right) {int mid = left + (right - left) / 2;if(nums[mid] < target) {left = mid + 1;}else if(nums[mid] > target) {right = mid;}else {return mid;}}return -1;}
}
全开(left,right)
分析同上述 只不过全开两种情况都赋值为mid.
class Solution {public int search(int[] nums, int target) { int right = nums.length;int left = -1;while(left + 1 < right) {int mid = left + (right - left) / 2;if(nums[mid] < target) {left = mid;}else if(nums[mid] > target) {right = mid;}else {return mid;}}return -1;}
}
Tips
1.区间问题,判断条件是否能遍历所有下标.
2.其实将mid取值方法改成left+((right-left)>>1)【和 / 2一样】是最好的,直接用(left+right)/ 2和(left+right)// 2 【向下取整】 只适用于少数据全包围情况,此情况left和right都是int范围,取值范围是-2147483648-2147483647,当两个数值很接近边界值的时候相加很容易出现负值
【向下取整】 只适用于少数据全包围情况,此情况left和right都是int范围,取值范围是-2147483648-2147483647,当两个数值很接近边界值的时候相加很容易出现负值**
3.(right-left )/ 2 只是表示了left和right指针之间距离的一半,不能表示mid所在的位置,用left加上距离的一半刚好能进行表示.
未完待续⭐