704 27总共用时不到一个小时,27思考了很多种方法,还有移动元素最少,花了点时间
704:一开始mid写错了,因为left right都会在变,mid=left+(right-left)/2 才对,不能只靠len
时间复杂度O(logn)
int search(vector<int>& nums, int target) {
int len=nums.size();
int mid=len/2;
int left=0;
int right=len-1;
while(left<=right){//<= 因为最后只有一个元素了也可以进行
//len=right-left+1;
//mid=len/2;
//上面两行是一开始写错的
mid = left + (right - left) / 2;
if(target==nums[mid]){
//find
return mid;
}
if(target<nums[mid]){
//lhs
right=mid-1;
}
else{
//rhs
left=mid+1;
}
}
return -1;
}
27:
方法一 暴力O(n*2) 用不用vec自带的erase都是
学到的东西:
c++11自带的auto 自动帮忙填充类型
vec可以用个resize
易错:不用erase自己写i的话,把后面的一次往前移动之后,当前i的内容就变了,要再查一次,所以有i--,不能忘了
//use vec erase
vector<int>::iterator it = nums.begin();
while(it != nums.end()) {
//for(auto it = nums.begin(); it != nums.end(); )
if(*it == val) {
it = nums.erase(it);
} else {
++it;
}
}
return nums.size();
//not use erase
int size=nums.size();
for (int i=0;i<size;i++){
if(nums[i]==val){
for(int j=i;j<size-1;j++){
nums[j]=nums[j+1];
}
size--;
//nums.resize(size);
i--;
}
}
return size;
方法二 双指针,思路:一个for loop做两个for的事,而且slow idx可以当作 new size,就不用再有一个size var
int slow=0;
int size=nums.size();
for( int fast=0;fast<nums.size();fast++){
if(nums[fast]!=val){
nums[slow++]=nums[fast];
}
else{
size--;
}
}
//return size;
return slow;
补充一个slow++知识:当这个操作独立出现,而不是作为更大表达式的一部分时,slow++
和++slow
具有相同的效果
27题还有个变体:确保移动最少元素,我自己是想不出来的,看了随想录的答案,和gpt一起学习理解的
idea:只需要遍历一次数组,而且最多只需要交换n次(n是数组的长度)
先不写上了,明天再自己做一次吧