704. 二分查找
二分查找涉及的很多的边界条件,逻辑比较简单,但就是写不好。例如到底是 while(left < right)
还是 while(left <= right)
,到底是right = middle
呢,还是要right = middle - 1
呢?
[left,right]写法:while的循环条件可以取等,因为left=right可以取到。判断分为三部分。(nums[mid] < target)时,left = mid+1,nums[mid]已经判断过了不是要找的值,(left是闭区间)下一轮还要取到left的值来判断,left不能取已经判断过的;(target < nums[mid])时,right = mid - 1,nums[mid]已经判断过了不是要找的值,(right是闭区间)下一轮还要取到right的值来判断,right不能取已经判断过的。
反例:nums = [0,2] target = 1。在第二次判断的时候,left = right,如果right = mid 而不是mid - 1的话,right没有办法移到left左边让while条件不成立跳出循环,从而陷入死循环。
package leetcode.editor.cn;
/**
* 二分查找
* @author DY
* @date 2024-07-23 10:59:52
*/
class P704_BinarySearch{
public static void main(String[] args) {
//测试代码
Solution solution = new P704_BinarySearch().new Solution();
int[] nums = {-1,0,3,5,9,12};
int[] nums1 = {0, 2};
int targets1 = 1;
System.out.println(solution.search(nums1, targets1));
}
//力扣代码
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int search(int[] nums, int target) {
if(nums.length == 0 ){
return -1;
}
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + (right - left)/2;
if(target < nums[mid]){
right = mid;
continue;
}else if(nums[mid] < target){
left = mid + 1;
continue;
}else{
return mid;
}
}
return -1;
}
}
//leetcode submit region end(Prohibit modification and deletion)
}
[left,right)写法:while条件不能取等,right取不到。(nums[mid] < target)时,left = mid+1,nums[mid]已经判断过了不是要找的值,(left是闭区间)下一轮还要取到left的值来判断,left不能取已经判断过的;(target < nums[mid])时,right = mid,nums[mid]已经判断过了不是要找的值,(right是开区间)下一轮不取到right的值来比较。
细节:(left + right)/2容易溢出。可以改成(left + rigth) >>>1 或者 left + (right- left)/2
27. 移除元素
题目链接:. - 力扣(LeetCode)
快慢指针解法:快指针:指针左边是已经遍历处理过的元素,右边反之;慢指针:选定作为输出的元素。
977.有序数组的平方
也是用双指针的写法,不同的是从两边往中间遍历。最后一遍遍历两个指针重叠时候仍然要判断,不然会漏掉元素。
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0,right = nums.length-1;
int temp = 0;
for(int i = 0; i < nums.length; i++){
nums[i] = nums[i] * nums[i];
}
for(int i = right; i > left; i--){
if(nums[i] >= nums[left]){
}else if(nums[i] < nums[left]){
temp = nums[i];
nums[i] = nums[left];
nums[left] = temp;
}
}
return nums;
}
}