前言:二分查找的思路简单,但是细节需要格外注意
二分查找
先看以下两份模板:
有序数组找到目标数并返回下标,没有就返回-1
1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public int search(int[] nums, int target) { int left = 0; int right = nums.length - 1; while (left <= right) { int mid = (left + right) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { left = mid + 1; } else if (nums[mid] > target) { right = mid - 1; } } return -1; }
|
2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public int search(int[] nums, int target) { int left = 0; int right = nums.length; while (left < right) { int mid = (left + right) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { left = mid + 1; } else if (nums[mid] > target) { right = mid; } } return -1; } }
|
上面两份代码的区别在于3处不同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int right = nums.length; 或者 int right = nums.length -1;
while (left < right) { } 或者 while (left <= right) { }
right = mid -1; 或者 right = mid;
|
这些不同在于区间
第一份代码区间为[left,right],左右区间都是闭合,所以right需要取length-1,循环条件只要left<=right就继续运行,right = mid - 1,因为mid值已经不等于target了。
第二份代码区间为[left,right),分析略。
当然以上的代码只适用只有一个目标值的情况
寻找左侧边界的二分搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| int left_bound(int[] nums, int target) { if (nums.length == 0) { return -1; } int left = 0; int right = nums.length;
while (left < right) { int mid = (left + right) / 2; if (nums[mid] == target) { right = mid; } else if (nums[mid] < target) { left = mid + 1; } else if (nums[mid] > target) { right = mid; } } if (left == nums.length) { return -1; } return nums[left] == target ? left : -1; }
|
区间为[left,right)
寻找右侧边界的二分搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| int right_bound(int[] nums, int target) { if (nums.length == 0) { return -1; } int left = 0, right = nums.length;
while (left < right) { int mid = (left + right) / 2; if (nums[mid] == target) { left = mid + 1; } else if (nums[mid] < target) { left = mid + 1; } else if (nums[mid] > target) { right = mid; } } if (left == 0) { return -1; } return nums[left - 1] == target ? (left - 1) : -1; }
|