赞
踩
二分查找,实际上也是左右双指针的变形,本质是利用数组的二段性进行查找。总共有三个模板:朴素二分、左边界二分、右边界二分
思路:
class Solution { public: int search(vector<int>& nums, int target) { int left = 0, right = nums.size() - 1; while(left <= right) { int mid = left + (right-left)/2; if(nums[mid] < target) left = mid + 1; else if(nums[mid] > target) right = mid - 1; else return mid; } return -1; } };
思路:
class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { if(nums.size() == 0) return {-1, -1}; int begin = -1, end = -1; int left = 0, right = nums.size() - 1; while(left < right) { int mid = left + (right-left)/2; if(nums[mid] >= target) right = mid; else left = mid + 1; } if(nums[left] == target) begin = left; left = 0, right = nums.size() - 1; while(left < right) { int mid = left + (right-left+1)/2; if(nums[mid] <= target) left = mid; else right = mid - 1; } if(nums[left] == target) end = left; return {begin, end}; } };
思路:
class Solution
{
public:
int mySqrt(int x)
{
int left = 1, right = x;
while(left < right)
{
long long mid = left + (right - left + 1) / 2;
if(mid * mid <= x) left = mid;
else right = mid - 1;
}
return right;
}
};
思路:
class Solution { public: int searchInsert(vector<int>& nums, int target) { if(target > nums.back()) return nums.size(); int left = 0, right = nums.size() - 1; while(left < right) { int mid = left + (right-left)/2; if(nums[mid] >= target) right = mid; else left = mid + 1; } return left; } };
思路:
class Solution
{
public:
int peakIndexInMountainArray(vector<int>& arr)
{
int left = 0, right = arr.size() - 1;
while(left < right)
{
int mid = left + (right-left)/2;
if(arr[mid] >= arr[mid+1]) right = mid;
else left = mid + 1;
}
return right;
}
};
思路:
class Solution
{
public:
int findPeakElement(vector<int>& nums)
{
int left = 0, right = nums.size() - 1;
while(left < right)
{
int mid = left + (right-left)/2;
if(nums[mid] >= nums[mid+1]) right = mid;
else left = mid + 1;
}
return left;
}
};
思路:
class Solution
{
public:
int findMin(vector<int>& nums)
{
int left = 0, right = nums.size() - 1;
while(left < right)
{
int mid = left + (right-left)/2;
if(nums[mid] <= nums[right]) right = mid;
else left = mid + 1;
}
return nums[left];
}
};
思路:
class Solution { public: int findMin(vector<int>& nums) { int left = 0, right = nums.size() - 1; while(left < right) { int mid = left + (right-left)/2; if(nums[mid] < nums[right]) right = mid; else if(nums[mid] == nums[right]) --right; else left = mid + 1; } return nums[left]; } };
二分查找,是一种十分高效的查找算法,时间复杂度为O(logN),在数组具有二段性时便可应用。
同时,只要掌握并理解了二分的模板,它便是最简单、最容易的一类题型~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。