有序数组 数组中无重复元素

704. 二分查找

  1. class Solution {
  2. public int search(int[] nums, int target) {
  3. int left = 0;
  4. int right = nums.length - 1; // 注意
  5. while(left <= right) {
  6. int mid = left + (right - left) / 2;
  7. if(nums[mid] == target)
  8. return mid;
  9. else if (nums[mid] < target)
  10. left = mid + 1; // 注意
  11. else if (nums[mid] > target)
  12. right = mid - 1; // 注意
  13. }
  14. return -1;
  15. }
  16. }
  17. // 详细解析参见:
  18. // https://labuladong.github.io/article/?qno=704

力扣34题

  1. /**
  2. * 范围查询规律
  3. * 初始化:
  4. * int left = 0;
  5. * int right = nums.length - 1;
  6. * 循环条件
  7. * left <= right
  8. * 右边取值
  9. * right = mid - 1
  10. * 左边取值
  11. * left = mid + 1
  12. * 查询条件
  13. * >= target值, 则 nums[mid] >= target时, 都减right = mid - 1
  14. * > target值, 则 nums[mid] > target时, 都减right = mid - 1
  15. * <= target值, 则 nums[mid] <= target时, 都加left = mid + 1
  16. * < target值, 则 nums[mid] < target时, 都加left = mid + 1
  17. * 结果
  18. * 求大于(含等于), 返回left
  19. * 求小于(含等于), 返回right
  20. * 示例(求> 或 >=)
  21. * private int search(int[] nums, int target) {
  22. * int left = 0;
  23. * int right = nums.length - 1;
  24. * while (left <= right){
  25. * int mid = (right - left) / 2 + left;
  26. * if (nums[mid] 查询条件 target){
  27. * right = mid - 1;
  28. * } else {
  29. * left = mid + 1;
  30. * }
  31. * }
  32. * return left(根据查询条件确认);
  33. * }
  34. * 核心思想: 要找某个值, 则查找时遇到该值时, 当前指针(例如right指针)要错过它, 让另外一个指针(left指针)跨过他(体现在left <= right中的=号), 则找到了
  35. */
  36. 作者:chendragon
  37. 链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-tong-yong-gui-lu-gu-ding-g93u/
  38. 来源:力扣(LeetCode
  39. 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

示例

  1. /**
  2. * 找数组中第一个 >= 目标值的索引
  3. * 没找到则返回数组长度值
  4. * 思路:
  5. * 大于等于都满足, 则不能取right值, 只能取与left相关的
  6. * 由于可以最大值都没有 >= 目标值, 故left要在遍历过程中达到 left > right
  7. * 故循环结束条件 left <= right
  8. * left要大于right, 则nums[mid] >= target时 right = mid - 1, 是right降到小于目标值的位置, 然后left跨过去
  9. * left 固定必须为 mid + 1
  10. * 没找到则返回数组长度值
  11. */
  12. public static int searchGeTarget(int[] nums, int target){
  13. int left = 0;
  14. int right = nums.length - 1;
  15. while (left <= right){
  16. int mid = (right - left) / 2 + left;
  17. if (nums[mid] >= target){
  18. right = mid - 1;
  19. } else {
  20. left = mid + 1;
  21. }
  22. }
  23. return left;
  24. }
  25. /**
  26. * 找数组中第一个 > 目标值的索引
  27. * 没找到则返回数组长度值
  28. */
  29. public static int searchGtTarget(int[] nums, int target){
  30. int left = 0;
  31. int right = nums.length - 1;
  32. while (left <= right){
  33. int mid = (right - left) / 2 + left;
  34. if (nums[mid] > target){
  35. right = mid - 1;
  36. } else {
  37. left = mid + 1;
  38. }
  39. }
  40. return left;
  41. }
  42. /**
  43. * 找数组第一个 <= 目标值的索引(4,4,4,4)的右边界
  44. * 没有则返回-1
  45. */
  46. public static int searchLeTarget(int[] nums, int target){
  47. int left = 0;
  48. int right = nums.length - 1;
  49. while (left <= right){
  50. int mid = (right - left) / 2 + left;
  51. if (nums[mid] > target){
  52. right = mid - 1;
  53. } else {
  54. left = mid + 1;
  55. }
  56. }
  57. return right;
  58. }
  59. /**
  60. * 找数组第一个 < 目标值的索引(4,4,4,4,5)的右边界5
  61. * 没有则返回-1
  62. */
  63. public static int searchLtTarget(int[] nums, int target){
  64. int left = 0;
  65. int right = nums.length - 1;
  66. while (left <= right){
  67. int mid = (right - left) / 2 + left;
  68. if (nums[mid] >= target){
  69. right = mid - 1;
  70. } else {
  71. left = mid + 1;
  72. }
  73. }
  74. return right;
  75. }

34题代码

  1. class Solution {
  2. /**
  3. * 二分查找
  4. */
  5. public int[] searchRange(int[] nums, int target) {
  6. //寻找左边界(这里寻找第一个 >= target的索引)
  7. int leftIndex = search(nums, target);
  8. if (leftIndex >= nums.length || nums[leftIndex] != target){
  9. return new int[]{-1, -1};
  10. }
  11. //寻找右边界(这里寻找第一个 >= target+1的索引)
  12. int rightIndex = search(nums, target + 1);
  13. return new int[]{leftIndex, rightIndex - 1};
  14. }
  15. /**
  16. * 寻找第一个>=目标值的索引, 找不到则返回数组长度
  17. */
  18. private int search(int[] nums, int target) {
  19. int left = 0;
  20. int right = nums.length - 1;
  21. while (left <= right){
  22. int mid = (right - left) / 2 + left;
  23. if (nums[mid] >= target){
  24. right = mid - 1;
  25. } else {
  26. left = mid + 1;
  27. }
  28. }
  29. return left;
  30. }
  31. }