LeetCode704二分查找
题目链接二分查找
思路:
二分查找首先要求在一个有序的数组中才能进行,然后取位于数组中间的值与目标数target作比较,若目标值大于中间值则下一次比较在区间右侧,反之左侧。二分查找中重要的地方在于区间的选取,是左右两边均为闭区间还是一个左闭右开的区间。
闭区间:
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;//未找到目标值
}
};
如果在循环时写成了left<right,就会有测试样例不通过,如果left=right,区间仍然是有效的。
左闭右开:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
int middle = left + ((right - left) >> 1);
if (nums[middle] > target) {
right = middle; // target 在左区间,在[left, middle)中
} else if (nums[middle] < target) {
left = middle + 1; // target 在右区间,在[middle + 1, right)中
} else { // nums[middle] == target
return middle; // 数组中找到目标值,直接返回下标
}
}
// 未找到目标值
return -1;
}
};
LeetCode27移除元素
思路:数组中由于数据的存放是连续的,所以删除元素时需要将右侧的所有元素向左移动一位。
暴力破解法:
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<size;j++)
{nums[j-1]=nums[j];}
i--;//下标i以后的数据全都向左移动了一位所以i也需要左移一位
size--;//数组长度减一
}
}
return size;
}
};
快慢指针法:
快慢指针法是定义两个指针
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size=nums.size();
int slowindex=0;
for(int fastindex=0;fastindex<size;fastindex++)
{
if(val!=nums[fastindex]){
nums[slowindex++]=nums[fastindex];
}
}
return slowindex;
}
};
相对快慢指针:
基于元素顺序可以改变的题目条件,得出移动元素最少的方案
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowindex=0;
int fastindex=nums.size()-1;
while(slowindex<=fastindex)
{
while(slowindex<=fastindex && nums[slowindex]!=val){
++slowindex;
}//从左边找和val相同的元素
while(slowindex<=fastindex && nums[fastindex]==val){
--fastindex;
}//从右边找与val不同的元素
if(slowindex < fastindex){
nums[slowindex++] =nums[fastindex--];
}//将右边的元素放到左边
}
return slowindex;//慢指针会指向下一个元素
}
};
总结:
今天主要学习了二分查找和数组中元素移除,二分查找中重点在于区间的选取,左闭右闭和左闭右开在循环判断条件上是不同的;而元素移除重点在于快慢指针的应用和理解。快指针是用来查找下一个新数组中的元素,慢指针是用来标出下一个元素的下标。