题目链接: . - 力扣(LeetCode)
1.二分法:
状态:没做出来,脑子里很迷糊,只能想到要比较,然后根据比较的结果缩小区间范围。那我该定义什么变量呢?肯定得有left和right,还得有个中间值middle。然后就卡住了,我一直在想要怎么遍历数组,然后我不知道要怎么把遍历数组和这玩意结合起来。
思路:但其实,二分法就是为了减少时间复杂度,就是为了不遍历所有元素。 所以,在接下来的循环也就是我们不断缩小寻找范围中,找循环条件应该是去想这个范围最小缩到多大呢。具体里面的判断条件就是要看,你选取的循环不变量(每次寻找的区间类型是左闭右开,还是左闭右闭)。
代码:(循环不变量是左闭右开)
class Solution {
public:
// 左闭右开
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();// 左闭右开,所以right可以取nums.size()
while(left < right){ //这里的条件直接看 left=right时是否有效
int middle = left + ((right - left)>>1);
// middle下标对应的元素不是我们的目标值,那我们下一次的区间范围就要排除它。然后就可以根据我们的循环不变量,来确定下一次区间边界的取值
if(target < nums[middle]){
right = middle; // 右边开区间
}else if(target > nums[middle]){
left = middle + 1; // 左边闭区间
}else {
return middle;
}
}
return -1;
}
};
(循环不变量是左闭右闭)
class Solution {
public:
// 左闭右闭
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;// 左闭右闭,所以right不可以取nums.size()
while(left <= right){ //这里的条件直接看 left=right时是否有效
int middle = left + ((right - left)>>1);
// middle下标对应的元素不是我们的目标值,那我们下一次的区间范围就要排除它。然后就可以根据我们的循环不变量,来确定下一次区间边界的取值
if(target < nums[middle]){
right = middle - 1; // 右边闭区间
}else if(target > nums[middle]){
left = middle + 1; // 左边闭区间
}else {
return middle;
}
}
return -1;
}
};
题目链接: . - 力扣(LeetCode)
2.移除元素
暴力法:
状态:暴力法思路很直接,可以写个大概,但是出现了两处错误。
一处是,我没有考虑到,在删除元素的过程中,我们的新数组的长度是在跟着变的!所以,我不能靠着“经验”,写 i < nums.size(),而是要用一个新变量size来记录新数组的长度,并且在两层循环的条件里都用size来做判断。
另一处是,我没有在删除元素后,考虑到 i 的值也要跟着递减,如果我不这样处理,我会漏掉要处理的元素,相当于我跳过了一个元素。
代码:
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]; //因为要删除nums[j-1],所以它就是第一个要被覆盖的。
}
i--; // 很容易漏掉,因为元素被删除了,所以i也应该减少一位
size--;
}
}
return size;
}
};
双指针法:
状态:我知道我大体思路了,也把循环写出来了。但是收到暴力法的影响,我又开始做什么fast--,size--的操作。但其实,因为这道题,我们没有用到后面的元素要向前移位的操作,所以,不要多想这些,fast就只是遍历一遍原数组,slow才用来修改,而且新数组的长度就正好等于slow。返回即可。
代码:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
// 双指针
int slow = 0;
for(int fast = 0; fast < nums.size();fast++){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
};