二分查找相关题目

二分法模板: https://www.acwing.com/blog/content/31/

有序数组中查找

1. LeetCode 34. Find First and Last Position of Element in Sorted Array

 1 class Solution {
 2 public:
 3     vector<int> searchRange(vector<int>& nums, int target) {
 4         vector<int> ans = {-1, -1};
 5         if(nums.size() == 0) return ans;
 6         int l=0, r=nums.size();
 7         // 找到最左边的元素
 8         while(l < r){
 9             int mid = l + (r - l) /2;
10             if(nums[mid] >= target)
11                 r = mid;
12             else
13                 l = mid + 1;
14         }
15         if(l==nums.size() || nums[l] != target)
16             return ans;
17     
18         ans[0] = l;
19         // 找最右边的元素
20         r = nums.size();
21         while(l < r){
22             int mid = l + (r - l) /2;
23             if(nums[mid] > target)
24                 r = mid;
25             else
26                  l = mid+1;
27             // 错误写法
28             //if(nums[mid] > target) r = mid - 1;
29             //else l = mid;     // 当l==mid, r保持不变时会死循环,
30         }
31         ans[1] = l-1;
32         return ans;
33     }
34 };

 有序数组的旋转

2. Leetcode 33. Search in Rotated Sorted Array https://leetcode.com/problems/search-in-rotated-sorted-array/

 1 class Solution {
 2 public:
 3     int search(vector<int>& nums, int target) {
 4         if(nums.empty()) return -1;
 5         int l=0, h=nums.size()-1;
 6         while(l < h){
 7             int mid = l + (h - l) / 2;
 8             // mid在旋转数组的尾端
 9             if(nums[mid] < nums[h])
10                 if(target > nums[mid] && target <= nums[h])
11                     l= mid + 1;
12                 else
13                     h = mid;
14             // mid在旋转数组的头端
15             else
16                 if(target >= nums[l] && target <= nums[mid])
17                     h = mid;
18                 else
19                     l = mid + 1;
20         }
21         return nums[l]==target ? l : -1;
22     }
23 };

无序数组也可以用二分搜索, 查找局部最大/最小值

3. LeetCode 162. Find Peak Element https://leetcode.com/problems/find-peak-element/

 1 class Solution {
 2 public:
 3     int findPeakElement(vector<int>& nums) {
 4         if(nums.empty()) return -1;
 5         int l=0, h=nums.size()-1;
 6         while(l < h){
 7             int mid = l + (h - l) / 2;
 8             if(nums[mid] < nums[mid+1])
 9                 l = mid + 1;
10             // 此时nums[mid]>nums[mid+1], 若nums[mid]>nums[mid-1],则nums[mid]
11             // 就是峰值,否则nums[mid]<nums[mid-1],表明峰值在左半区间。画图看一下就明白了
12             else
13                 h = mid;
14         }
15         return l;
16     }
17 };

4. LeetCode 287. Find the Duplicate Number https://leetcode.com/problems/find-the-duplicate-number/

 1 class Solution {
 2 public:
 3     int findDuplicate(vector<int>& nums) {
 4         int l=1, n=nums.size(), h=n-1;
 5         // l,h不是索引,是数的取值范围
 6         while(l < h){
 7             int mid = l + (h - l) / 2;   // 中间大小的数
 8             int cnt=0;                   // 计算比mid小的数有几个
 9             for(int i=0; i<n; ++i)
10                 if(nums[i] <= mid)
11                     ++cnt;
12             // 比mid小的数个数比mid大,表明1~mid中间有重复的数字
13             if(cnt > mid)    
14                 h = mid;
15             else
16                 l = mid + 1;
17         }
18         return l;
19     }
20 };
原文地址:https://www.cnblogs.com/sclczk/p/11162712.html