二分查找算法虽然简单,却是笔试和面试题中出现的高频题,经常用来在有序的数组或者矩阵中查找某个特定的位置。
二分法简单介绍:
(1)算法定义:
(2)基本思想:
(3)优缺点:
LeetCode中关于排序的题目有以下四种类型题:
(一)二分法之普通排序数组相关题目:
(二)二分法之变形排序数组相关题目:
(三)二分法之排序矩阵相关题目:
(四)二分法之实例应用相关题目:
704. Binary Search
nums
of n
elements and a target
value, write a function to search target
in nums
. If target
exists, then return its index, otherwise return -1
.target
,用O(logn)
的时间查找到target出现的下标(从0开始),如果target不存在于数组中,返回-1
。class Solution {
public:
int search(vector& nums, int target) {
int low = 0, high = nums.size() - 1, mid = 0;
while(low <= high){
mid = low + (high - low) / 2;
if(nums[mid] < target) low = mid + 1;
else if(nums[mid] > target) high = mid - 1;
else return mid;
}
return -1;
}
};
35. Search Insert Position
class Solution {
public:
int searchInsert(vector& nums, int target) {
int low = 0, high = nums.size() - 1, mid = 0;
while(low <= high){
mid = low + (high - low) / 2;
if(nums[mid] < target) low = mid + 1;
else if(nums[mid] > target) high = mid - 1;
else return mid;
}
return low;
}
};
34. Find First and Last Position of Element in Sorted Array
nums
sorted in ascending order, find the starting and ending position of a given target
value. Your algorithm's runtime complexity must be in the order of O(log n). If the target is not found in the array, return [-1, -1]
.class Solution {
public:
vector searchRange(vector& nums, int target) {
vector res(2,-1);
int n = nums.size(), low = 0, high = n - 1, mid = 0;
if(n == 0) return res;
while(low < high){
mid = low + (high - low) / 2;
if(nums[mid] < target) low = mid + 1;
else if(nums[mid] > target) high = mid - 1;
else high = mid;
}
if(nums[low] == target) res[0] = low;
else return res;
high = n - 1;
while(low <= high){
mid = low + (high - low) / 2;
if(nums[mid] < target) low = mid + 1;
else if(nums[mid] > target) high = mid - 1;
else low = mid + 1;
}
res[1] = low - 1;
return res;
}
};
33. Search in Rotated Sorted Array
[0,1,2,4,5,6,7]
might become [4,5,6,7,0,1,2]
). You are given a target value to search. If found in the array return its index, otherwise return -1
. You may assume no duplicate exists in the array. Your algorithm's runtime complexity must be in the order of O(log n).class Solution {
public:
int search(vector& nums, int target) {
int n= nums.size(), low = 0, high = n - 1, mid = 0;
while(low <= high){
mid = low + (high - low) / 2;
if(nums[mid] == target) return mid;
if(nums[low] <= nums[mid]){
if(nums[low] <= target && nums[mid] >= target) high = mid - 1;
else low = mid + 1;
}else{
if(nums[high] >= target && nums[mid] <= target) low = mid + 1;
else high = mid - 1;
}
}
return -1;
}
};
81. Search in Rotated Sorted Array II
[0,0,1,2,2,5,6]
might become [2,5,6,0,0,1,2]
). You are given a target value to search. If found in the array return true
, otherwise return false
.class Solution {
public:
bool search(vector& nums, int target) {
int n= nums.size(), low = 0, high = n - 1, mid = 0;
while(low <= high){
mid = low + (high - low) / 2;
if(nums[mid] == target) return true;
if(nums[low] < nums[mid]){
if(nums[low] <= target && nums[mid] >= target) high = mid - 1;
else low = mid + 1;
}else if(nums[low] > nums[mid]){
if(nums[high] >= target && nums[mid] <= target) low = mid + 1;
else high = mid - 1;
}else{
low++;
}
}
return false;
}
};
153. Find Minimum in Rotated Sorted Array
[0,1,2,4,5,6,7]
might become [4,5,6,7,0,1,2]
). Find the minimum element. You may assume no duplicate exists in the array.4,5,6,7,0,1,2
}为{0,1,2,4,5,6,7
}的一个旋转,该数组的最小值为0。class Solution {
public:
int findMin(vector& nums) {
int n = nums.size(), low = 0, high = n - 1, mid = 0;
while(low < high){
if(nums[low] < nums[high]) return nums[low];
mid = (low + high) / 2;
if(nums[mid] > nums[high]) low = mid + 1;
else high = mid;
}
return nums[low];
}
};
154. Find Minimum in Rotated Sorted Array II
[0,1,2,4,5,6,7]
might become [4,5,6,7,0,1,2]
). Find the minimum element. The array may contain duplicates.4,5,6,7,0,1,2
}为{0,1,2,4,5,6,7
}的一个旋转,该数组的最小值为0。class Solution {
public:
int findMin(vector& nums) {
int n = nums.size(), low = 0, high = n - 1, mid = 0;
while(low < high){
if(nums[low] < nums[high]) return nums[low];
mid = (low + high) / 2;
if(nums[mid] > nums[high]) low = mid + 1;
else if(nums[mid] < nums[high]) high = mid;
else high--;
}
return nums[low];
}
};
74. Search a 2D Matrix
class Solution {
public:
bool searchMatrix(vector>& matrix, int target) {
if(matrix.empty() || matrix[0].empty()) return false;
if(target < matrix[0][0] || target > matrix.back().back()) return false;
int m = matrix.size(), n = matrix[0].size();
int low = 0, high = m * n - 1, mid = 0, temp = 0;
while(low <= high){
mid = low + (high - low) / 2;
temp = matrix[mid / n][mid % n];
if(temp > target) high = mid - 1;
else if(temp < target) low = mid + 1;
else return true;
}
return false;
}
};
240. Search a 2D Matrix II
class Solution {
public:
bool searchMatrix(vector>& matrix, int target) {
if(matrix.empty() || matrix[0].empty()) return false;
if(target < matrix[0][0] || target > matrix.back().back()) return false;
int x = matrix.size() - 1, y = 0;
while(true){
int temp = matrix[x][y];
if(temp < target) y++;
else if(temp > target) x--;
else return true;
if(x < 0 || y >= matrix[0].size()) break;
}
return false;
}
};
378. Kth Smallest Element in a Sorted Matrix
class Solution {
public:
int kthSmallest(vector>& matrix, int k) {
int row = matrix.size(), col = matrix[0].size();
int low = matrix[0][0], high = matrix[row - 1][col - 1];
while(low < high){
int mid = (low + high) / 2, j = col - 1, cnt = 0;
for(int i = 0; i < row; i++){
while(j >=0 && matrix[i][j] > mid)j--;
cnt +=(j + 1);
}
if(cnt < k) low = mid + 1;
else high = mid;
}
return low;
}
};
374. Guess Number Higher or Lower
guess(int num)
which returns 3 possible results (-1
, 1
, or 0
):// Forward declaration of guess API.
// @param num, your guess
// @return -1 if my number is lower, 1 if my number is higher, otherwise return 0
int guess(int num);
class Solution {
public:
int guessNumber(int n) {
int low = 1, high = n, mid = 0, temp = 0;
while(low <= high){
mid = low + (high - low) / 2;
temp = guess(mid);
if(temp == -1) high = mid - 1;
else if(temp == 1) low = mid + 1;
else return mid;
}
return -1;
}
};
278. First Bad Version
n
versions [1, 2, ..., n]
and you want to find out the first bad one, which causes all the following ones to be bad. You are given an API bool isBadVersion(version)
which will return whether version
is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int low = 1, high = n, mid = 0;
while(low < high){
mid = low + (high - low) / 2;
bool temp = isBadVersion(mid);
if(temp) high = mid;
else low = mid + 1;
}
return low;
}
};
275. H-Index II
class Solution {
public:
int hIndex(vector& nums) {
int n = nums.size(), low = 0, high = n - 1, mid = 0;
while(low <= high){
mid = low + (high - low) / 2;
int target = n - mid;
if(nums[mid] < target) low = mid + 1;
else if(nums[mid] > target) high = mid - 1;
else return n - mid;
}
return n - low;
}
};
274. H-Index
class Solution {
public:
int hIndex(vector& nums) {
sort(nums.begin(), nums.end());
int n = nums.size(), low = 0, high = n - 1, mid = 0;
while(low <= high){
mid = low + (high - low) / 2;
int target = n - mid;
if(nums[mid] < target) low = mid + 1;
else if(nums[mid] > target) high = mid - 1;
else return n - mid;
}
return n - low;
}
};
162. Find Peak Element
nums
, where nums[i] ≠ nums[i+1]
, find a peak element and return its index. The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. You may imagine that nums[-1] = nums[n] = -∞
.class Solution {
public:
int findPeakElement(vector& nums) {
int n = nums.size(), low = 0, high = n - 1;
while(low < high){
int mid1 = (low + high) / 2, mid2 = mid1 + 1;
if(nums[mid1] < nums[mid2]) low = mid2;
else high = mid1;
}
return low;
}
};
852. Peak Index in a Mountain Array
A
a mountain if the following properties hold: A.length >= 3
There exists some 0 < i < A.length - 1
such that A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]
Given an array that is definitely a mountain, return any i
such that A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]
.class Solution {
public:
int peakIndexInMountainArray(vector& nums) {
int n = nums.size(), low = 0, high = n - 1;
while(low < high){
int mid = (low + high) / 2;
if(nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1]) return mid;
if(nums[mid] < nums[mid + 1]) low = mid + 1;
else high = mid;
}
return low;
}
};
如果各位看官们,大神们发现了任何错误,或是代码无法通过OJ,或是有更好的解法,或是有任何疑问,意见和建议的话,请一定要在帖子下面评论区留言告知博主啊,多谢多谢,祝大家刷得愉快,刷得精彩,刷出美好未来~