您现在的位置是:首页 >学无止境 >代码随想录算法训练营第一天 | 704. 二分查找、27. 移除元素网站首页学无止境
代码随想录算法训练营第一天 | 704. 二分查找、27. 移除元素
简介代码随想录算法训练营第一天 | 704. 二分查找、27. 移除元素
二分搜索
思路及值得注意的点
1.数组要有序
2.值得注意的点
区间的开闭锁所导致的边界条件的不同
左闭右闭区间
target在区间[left,right]中
右边是闭区间,所以:
- 首先right=nums.size()-1,且 left<=right
- if(nums[mid]>taget)时 要在左半区间查找时 因为是闭区间所以 nums[mid] 已经比较过了,一定不是我们要搜索的值,所以 right=mid-1;
同理 if(nums[mid]<taget) 时更新左区间 left = mid+1;
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() -1; //注意
while( left <= right )
{
int mid = left + ( right - left) / 2;
if( nums[mid] > target)
{
right = mid - 1;//注意
}
else if( nums[mid] <target )
{
left = mid + 1;//注意
}
else
{
return mid;
}
}
return -1;
}
左闭右开区间
target在区间[left,right)中
右边是闭区间,所以:
- 首先right=nums.size(),且 left<right,
- if(nums[mid]>taget)时 要在左半区间查找时 因为是开区间所以 nums[mid] 没有比较过,所以要在这里比较一下,所以 right=mid;
同理 if(nums[mid]<taget) 时更新左区间 ,左边是闭区间,所以left = mid+1;
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() ;
while( left < right )
{
int mid = left + ( right - left) / 2;
if( nums[mid] > target)
{
right = mid;
}
else if( nums[mid] <target )
{
left = mid + 1;
}
else
{
return mid;
}
}
return -1;
}
寻找左边界以及右边界
想法很简单,就是当nums[mid] == target时继续往左或这往右移动
只要注意处理一下最后的返回值即可
int searchleft(vector<int>& nums, int target){
int left = 0;
int right = nums.size() -1;// left的值>=nums.size()时终止
while( left <= right )
{
int mid = left + ( right - left) / 2;
if( nums[mid] > target)
{
right = mid - 1;
}
else if( nums[mid] <target )
{
left = mid + 1;
}
else if(nums[mid] == target)
{
right = mid - 1; //右边界不断往左收缩
}
}
if(left >= nums.size() || nums[left]!=target) return -1;//终止条件是 left = right + 1;
return left;
}
int searchright(vector<int>& nums, int target){
int left = 0; //right<0终止
int right = nums.size() -1;
while( left <= right )
{
int mid = left + ( right - left) / 2;
if( nums[mid] > target)
{
right = mid - 1;
}
else if( nums[mid] <target )
{
left = mid + 1;
}
else
{
left = mid + 1;
}
}
if( right < 0 || nums[right] !=target) return -1; //right < left 时终止
return right;
}
移除元素
双指针法实现,快慢指针或者收尾指针都可以,关键在于一个指针维护结果数组的位置(slow),一个指针遍历初始数组的位置来判断元素(fast)
int removeElement(vector<int>& nums, int val) {
int n=nums.size();
if(n==0) return 0;
int slow=0;
for(int fast=0;fast<n;++fast)
{
if(nums[fast] != val)
{
nums[slow]=nums[fast];
++slow;
}
}
return slow;
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。