二分查找有三个常用的模板,对应每个模板,我会不断更新我写过中高等题及供记忆与交流。
想系统学习的可以戳这个->(leetbook参考链接)
模板1
模板 #1
用于查找可以通过访问数组中的单个索引来确定的元素或条件。
int binarySearch(vector<int>& nums, int target){
if(nums.size() == 0)
return -1;
int left = 0, right = nums.size() - 1;
while(left <= right){
// Prevent (left + right) overflow
int mid = left + (right - left) / 2;
if(nums[mid] == target){ return mid; }
else if(nums[mid] < target) { left = mid + 1; }
else { right = mid - 1; }
}
// End Condition: left > right
return -1;
}
33.搜索旋转排序数组
int search(int* nums, int numsSize, int target){
int l = 0;
int r = numsSize - 1;
while(l <= r)
{
int mid = (l + r) / 2;
if(nums[mid] == target) return mid;
if(nums[mid] >= nums[l])//左边有序
{
if(nums[l] <= target && nums[mid] > target) r = mid - 1;//目标值在左面
else l = mid + 1;
}
else//右边有序
{
if(nums[r] >= target && nums[mid] < target) l = mid + 1;//目标值在右面
else r = mid - 1;
}
}
return -1;
}
34.在排序数组中查找元素的第一个和最后一个位置
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* searchRange(int* nums, int numsSize, int target, int* returnSize){
int l = 0;
int r = numsSize - 1;
int mid = 0;
int ans = numsSize;
int * ret = malloc(sizeof(int) * 2);
* returnSize = 2;
if(numsSize ==0)
{
ret[0] = -1;
ret[1] = -1;
return ret;
}
while(l <= r)
{
mid = l + (r - l) / 2;
if(nums[mid] >= target) {
r = mid - 1;
ans = mid;
}
else l = mid + 1;
}
ret[0] = ans;
l = 0;
r = numsSize - 1;
ans = numsSize;
mid = 0;
while(l <= r)
{
mid = l + (r - l) / 2;
if(nums[mid] > target) {
r = mid - 1;
ans = mid;
}
else l = mid + 1;
}
ret[1] = ans - 1;
if(ret[0]<=ret[1] && ret[1]<numsSize && nums[ret[0]] == target && nums[ret[1]] == target)
return ret;
ret[0] = -1, ret[1] = -1;
return ret;
}
模板2
模板 #2
是二分查找的高级模板。它用于查找需要访问数组中当前索引及其直接右邻居索引的元素或条件。
int binarySearch(vector<int>& nums, int target){
if(nums.size() == 0)
return -1;
int left = 0, right = nums.size();
while(left < right){
// Prevent (left + right) overflow
int mid = left + (right - left) / 2;
if(nums[mid] == target){ return mid; }
else if(nums[mid] < target) { left = mid + 1; }
else { right = mid; }
}
// Post-processing:
// End Condition: left == right
if(left != nums.size() && nums[left] == target) return left;
return -1;
}
162.寻找峰值
int findPeakElement(int* nums, int numsSize){
int l = 0;
int r = numsSize - 1;
while(l < r)
{
int mid = l + (r - l) / 2;
if(nums[mid] < nums[mid+1])
l = mid + 1;
else
r = mid;
}
return l;
}
153.寻找旋转排列数组中的最小值
int findMin(int* nums, int numsSize){
int l = 0;
int r = numsSize - 1;
if(nums[r] > nums[l])return nums[l];
while(l < r)
{
int mid = l + (r - l) / 2;
if(nums[mid] > nums[mid+1])
return nums[mid+1];
else if(nums[mid-1] > nums[mid])
return nums[mid];
if(nums[mid] > nums[l])//左边有序
l = mid + 1;
else//右边有序
r = mid;
}
return nums[0];
}
模板3
模板 #3
是二分查找的另一种独特形式。 它用于搜索需要访问当前索引及其在数组中的直接左右邻居索引的元素或条件。
int binarySearch(vector<int>& nums, int target){
if (nums.size() == 0)
return -1;
int left = 0, right = nums.size() - 1;
while (left + 1 < right){
// Prevent (left + right) overflow
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid;
} else {
right = mid;
}
}
// Post-processing:
// End Condition: left + 1 == right
if(nums[left] == target) return left;
if(nums[right] == target) return right;
return -1;
}