当前位置:   article > 正文

【Algorithm】优选算法: 二分查找 binary search 核心思想与例题总结

【Algorithm】优选算法: 二分查找 binary search 核心思想与例题总结

        二分查找算法是利用数组的二段性进行求解的算法。只要有二段性的数组,都能使用该方法进行求解。

        目录>>

一、核心思想

二、例题总结

1. 704.二分查找 search

2. 34.在排序数组中查找元素的第一个和最后一个位置 searchRange

3. 35.搜索插入位置 searchInsert

4. 69.×的平方根 mySqrt

5. 852.山脉数组的峰顶索引 peakIndexInMountainArray

6. 162.寻找峰值 findPeakElement

7. 153.寻找旋转排序数组中的最小值 findMin

8. LCR 173.点名 takeAttendance


一、核心思想

        二分查找算法是利用数组的二段性进行求解的算法。只要有二段性的数组,都能使用该方法进行求解。

        找出数组的二段性,运用二分查找进行求解。

二、例题总结

1. 704.二分查找 search

 朴素二分查找。

  1. class Solution {
  2. public int search(int[] nums, int target) {
  3. int left = 0;
  4. int right = nums.length - 1; //右端点
  5. // int mid = (left + right)/2; 容易溢出
  6. while (left <= right){
  7. int mid = left + (right - left) / 2; //先求区间的一半,防溢出
  8. // int mid = left + (right - left) / 3; //区间的三分之一
  9. if (nums[mid] < target) left = mid+1;
  10. else if (nums[mid] > target) right = mid-1;
  11. else return mid;
  12. }
  13. return -1;
  14. }
  15. }

2. 34.在排序数组中查找元素的第一个和最后一个位置 searchRange

  1. class Solution {
  2. public int[] searchRange(int[] nums, int target) {
  3. // 处理边界
  4. int[] ret = new int[2];
  5. ret[0] = ret[1] = -1;
  6. if (nums.length == 0) return ret;
  7. // 1,二分左端点
  8. int left = 0;
  9. int right = nums.length - 1;
  10. while (left<right){
  11. int mid = left + (right - left) / 2;
  12. if (nums[mid] < target) left = mid +1;
  13. else right = mid;
  14. }
  15. // 判断是否有结果
  16. if (nums[left] != target) return ret;
  17. else ret[0] = right;
  18. // 2,二分右端点
  19. left = 0;
  20. right = nums.length-1;
  21. while (left<right){
  22. int mid = left + (right - left + 1) / 2;
  23. if (nums[mid] <= target) left = mid;
  24. else right = mid -1;
  25. }
  26. ret[1] = left;
  27. return ret;
  28. }
  29. }

3. 35.搜索插入位置 searchInsert

  1. class Solution {
  2. public int searchInsert(int[] nums, int target) {
  3. int left = 0, right = nums.length - 1;
  4. while (left < right){
  5. int mid = left + (right - left) / 2;
  6. if (nums[mid] < target) left = mid+1;
  7. else right = mid;
  8. }
  9. //target比最小的数小,放最左边
  10. if (nums[left] < target) return left + 1;
  11. return left;
  12. }
  13. }

4. 69.×的平方根 mySqrt

  1. class Solution {
  2. public int mySqrt(int x) {
  3. if(x < 1) return 0;
  4. long left = 1, right = x;
  5. while(left < right)
  6. {
  7. long mid = left + (right - left + 1) / 2;
  8. if(mid * mid <= x) left = mid;
  9. else right = mid - 1;
  10. }
  11. return (int)left;
  12. }
  13. }

5. 852.山脉数组的峰顶索引 peakIndexInMountainArray

  1. class Solution {
  2. public int peakIndexInMountainArray(int[] arr) {
  3. int left = 1, right = arr.length - 2;
  4. while(left < right){
  5. int mid = left + (right - left + 1) / 2;
  6. if(arr[mid] > arr[mid - 1]) left = mid;
  7. else right = mid - 1;
  8. }
  9. return left;
  10. }
  11. }

6. 162.寻找峰值 findPeakElement

  1. class Solution {
  2. public int findPeakElement(int[] nums) {
  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] < nums[mid+1]) left = mid + 1;
  8. else right = mid;
  9. }
  10. return left;
  11. }
  12. }

7. 153.寻找旋转排序数组中的最小值 findMin

  1. class Solution {
  2. public int findMin(int[] nums) {
  3. int left = 0, right = nums.length - 1;
  4. int x = nums[right]; // 标记⼀下最后⼀个位置的值
  5. while(left < right){
  6. int mid = left + (right - left) / 2;
  7. if(nums[mid] > x) left = mid + 1;
  8. else right = mid;
  9. }
  10. return nums[left];
  11. }
  12. }

8. LCR 173.点名 takeAttendance

一题多解,需要发散思维。

运用 哈希表直接遍历异或运算高斯求和 都能求解出结果,时间复杂度都是O(n)。

但是运用 二分查找 来求解,时间复杂度就是O(logN)。

  1. int left = 0;
  2. int right = records.length - 1;
  3. while (left < right){
  4. int mid = left + (right - left) / 2;
  5. if (records[mid] == mid) left = mid +1;
  6. else right = mid;
  7. }
  8. // 细节eg,数组0,1,2,3,缺少4
  9. return records[left] == left ? left + 1 : left;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/831120
推荐阅读
相关标签
  

闽ICP备14008679号