- 参考了B站视频,感觉分析得很到位,再也不用被魔鬼细节折磨了,链接如下:
-
二分查找常见场景:
以{ 1, 6, 6, 6, 7}为例,假设目标值为6:
- 查找目标值左边界的坐标 ---- 0
- 查找目标值左边界左边值的坐标 ---- 1
- 查找目标值右边界的坐标 ---- 3
- 查找目标值右边界右边值的坐标 ---- 4
- 数据无重复的情况下找目标值,参考场景1和场景3
-
实现细节(N为数组长度)
- left = -1;
- right = N;
- mid = left + (right - left) / 2;
- 循环条件 while( (left + 1) != rigtht)
- 对于场景2和场景4,有可能遇到返回值分别为-1和N的场景,可以自行处理。(例如{ 6, 6, 6, 6, 6},场景2返回的坐标是-1,场景4返回的坐标是6)
-
代码实现:
-
package BinarySearch; /* * 二分查找的典型情况: * 1.找左边界 * 2.找左边界的左值 * 3.找右边界 * 4.找右边界的右值 * */ public class BinarySearch { public static void main(String[] args) { int[] nums = new int[]{0, 1, 1, 1, 6, 6, 6, 7}; System.out.println(searchRightOfTarget(nums, 6)); System.out.println(searchLeftOfTarget(nums, 1)); System.out.println(searchLeftTarget(nums, 6)); System.out.println(searchRightTarget(nums, 6)); } private static int searchRightOfTarget(int[] nums, int target) { if (nums.length == 0) { return -1; } int left = -1; int right = nums.length; int mid = 0; while ((left + 1) != right) { mid = left + (right - left) / 2; if (nums[mid] > target) { right = mid; } else { left = mid; } } return right; } private static int searchLeftOfTarget(int[] nums, int target) { if (nums.length == 0) { return -1; } int left = -1; int right = nums.length; int mid = 0; while ((left + 1) != right) { mid = left + (right - left) / 2; if (nums[mid] >= target) { right = mid; } else { left = mid; } } return left; } private static int searchRightTarget(int[] nums, int target) { if (nums.length == 0) { return -1; } int left = -1; int right = nums.length; int mid = 0; while ((left + 1) != right) { mid = left + (right - left) / 2; if (nums[mid] > target) { right = mid; } else { left = mid; } } return left; } private static int searchLeftTarget(int[] nums, int target) { if (nums.length == 0) { return -1; } int left = -1; int right = nums.length; int mid = 0; while ((left + 1) != right) { mid = left + (right - left) / 2; if (nums[mid] >= target) { right = mid; } else { left = mid; } } return right; } }