704.二分查找
1.左闭右闭
思路:left表示数组的第一个元素的下标,right表示数组的最后一个元素的下标,mid代表数组的中间元素的下标,如果arr[mid]<val(val表示要查找的值),那么left=mid+1;如果arr[mid]>val(val表示要查找的值),那么right=mid-1;如果arr[mid]==val,则返回mid的值。
注意,循环条件是left<=right,因为是左左闭右闭,所以如果left==right,就表示一个元素,这时也能查找,除非left>right,说明已经没有元素了。
2.左闭右开
跟左闭右闭的唯一区别是,因为是右开,所以最右边的元素是取不到的,所以最开始初始化right=nums.size(),同时,因为是右开,所以循环条件是left<right,因为left<right说明有超过1的元素个数,如果left>=right,是没有元素的,还要注意,如果arr[mid]>val(val表示要查找的值),那么right-1,那么right=mid,因为右边是取不到的,所以如果right=mid-1,就取不到mid左边的元素了
class Solution {
public:
int search(vector<int>& nums, int target)
{
//左闭右闭
// int left = 0;
// int right = nums.size() - 1;
// while (left <= right)
// {
// int middle = left + (right - left) / 2;
// if (nums[middle] > target)
// {
// right = middle - 1;
// }
// else if (nums[middle] < target)
// {
// left= middle + 1;
// }
// else
// {
// return middle;
// }
// }
// return -1;
// }
//左闭右开
int left = 0;
int right = nums.size() ;
while (left < right)
{
int middle = left + (right - left) / 2;
if (nums[middle] > target)
{
right = middle;
}
else if (nums[middle] < target)
{
left= middle + 1;
}
else
{
return middle;
}
}
return -1;
}
};
27.移除元素
1.暴力解
直接来一个for循环遍历数组的所有元素,如果找到了要移除的元素,则将这个元素后面的元素依次覆盖前面的元素,即把它们一个个往前挪动。
2.双指针1(难)
设置pre=0;cur=0;将cur遍历,如果arr[i]!=val(要查找的值),那么arr[pre++]=arr[cur],即pre++,表示pre会往后面移动一位,如果arr[i]==val,那么只有cur移动,pre还在原来的位置,cur不断++,直到找到不是val的值,那么将该值赋值给pre所在的位置,这时候pre才可以继续往前移动,达到将不是val的值不断往前移动,实现覆盖的效果。
3.双指针2(难)
设置left=0;right=nums.size()-1;如果left<=right(注意,这里=是考虑如果left>right,因为left是一个一个动的,所以这时候left肯定在right的右边,那么这是left代表的就是数组的长度)&&arr[left]!=val,那么left可以不断往右移动,直到找到对应的val值,这时候,右边的指针(并不是指针,只是个比喻)right就可以开始移动了,只要它所指的值不是val,那么就可以不用移动,直接把这个值赋值给被删除元素的位置,然后right--就实现了把最右边不是val的值赋值给val原本所在的位置,并且这时候又会实现长度自动减一的结果;如果它所指的值是val,那么肯定要往左边移动,因为val本来就是要被删除的,right--其实就实现了删除右边多余的val的值。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
//暴力解
// int size=nums.size();
// for(int i=0;i<size;i++)
// {
// if(nums[i]==val)
// {
// for(int j=i+1;j<nums.size();j++)
// {
// nums[j-1]=nums[j];
// }
// i--;
// size--;
// }
// }
// return size;
// }
//双指针
// int pre=0;
// for(int i=0;i<nums.size();i++)
// {
// if(nums[i]!=val)
// {
// nums[pre++]=nums[i];
// }
// }
// return pre;
// }
//双向指针
int left=0;
int right=nums.size()-1;
while(left<=right)
{
while(left<=right&&nums[left]!=val)
left++;
while(left<=right&&nums[right]==val)
right--;
if(left<right)
{
nums[left++]=nums[right--];
}
}
return left;
}
};