难点可能在:插入位置,寻找左/右边界,处理超出int大小
代码随想录算法训练营第1天 | 704二分查找,27移除元素_weixin_51674457的博客-CSDN博客
代码随想录额外题目| 数组03 ●34排序数组查首尾位置 ●922按奇偶排序数组II●35搜索插入位置_weixin_51674457的博客-CSDN博客
难点可能在:写满足[slow++]的条件,巧妙的遍历顺序(两头向中间)
代码随想录算法训练营第1天 | 704二分查找,27移除元素_weixin_51674457的博客-CSDN博客
代码随想录算法训练营第2天 | 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结_weixin_51674457的博客-CSDN博客
69,367 第一次做,其他二刷
704二分查找 很快, 用(start+end)/2 不容易错
35找插入位置,很快,巧妙,没找到直接return end-1或者start(最终结果只会剩下一个元素:即mid=start=end,要是target<[start], 答案就是start,要是target>[start] 我们需要插入在start+1,而start确实会变成mid+1=start+1,所以又只用return start了)
34 寻找target段头尾,略微变体为寻找左右边界(大于小于情况不变,等于时找左边界那我们还是要改变end往左移动,找右边界还是要改变start往右边移动,并且要不断更新border为mid)因为我第一次不是这样做的,是先找到target再不断左右移动,其实也没差,所以我不太会用二分找左右边界,这回思路理顺后应该会了
vector searchRange(vector& nums, int target) {
int start=0; int end=nums.size()-1;
int right_idx=-1;
int left_idx=-1;
//find right
while(start<=end){
int mid=(start+end)/2;
if(targetnums[mid]) start=mid+1;
else{//equal case
right_idx=mid;
start=mid+1;
}
}
//find left
start=0; end=nums.size()-1;
while(start<=end){
int mid=(start+end)/2;
if(targetnums[mid]) start=mid+1;
else{//equal case
left_idx=mid;
end=mid-1;
}
}
return {left_idx,right_idx};
}
69 x sqrt
有点像35插入位置,mid*mid数值会过大,需要处理用size_t 或者 改用x/mid,两种都在下面
int mySqrt(int x) {
int start=0; int end=x;
while(start<=end){
size_t mid=(start+end)/2;
if(mid*mid==x) return mid;
else if(mid*mid
367 perfect sqrt 和 69 sqrt几乎一样,就是不能用除法,一定要用mid*mid
bool isPerfectSquare(int num) {
int start=1;
int end=num;
while(start<=end){
size_t mid=start+(end-start)/2;
if(mid*mid==num) return true;
else if (mid*mid
27移除元素 标准双指针 slow fast,fast作主itr,只有符合要求才从头放起[slow++]
26删除排序重复 一模一样,只有判断条件变了
int removeDuplicates(vector& nums) {
int slow=0;
int fast=0;
while(fast
844.比较含退格的字符串
我一刷想的特别复杂,其实跟前面也类似,就是从头看起,符合要求就加入,符合另一个要求,就把str 尾巴去掉一个,这里注意 str也有pop_back的操作的
string helper(string str){
string ans="";
for(char &c:str){
if(c!='#') ans+=c;
else if(ans.size()) ans.pop_back();
}
return ans;
}
bool backspaceCompare(string s, string t) {
return helper(s)==helper(t);
}
977.有序数组的平方 双指针从尾巴开始,有点巧
我从中间分开向两头做,代码和逻辑会很复杂,随想录是从头尾向中间收拢,逻辑简单太多
从中间往两头写特别麻烦(我写的)这时候就应该想到从两头往中间写(随想录)
my code 中间到两头
vector sortedSquares(vector& nums) {
vector res;
int mid=0;
if(nums[0]>=0) mid=0;
else if(nums[nums.size()-1]<0) mid=nums.size()-1;
for(int i=1;i=0) mid=i;
}
int i=mid-1; int j=mid;
while(i>=0 || j=nums.size()){
res.push_back(nums[i]*nums[i]);
i--;
}
else if(nums[i]*nums[i]<=nums[j]*nums[j]){
res.push_back(nums[i]*nums[i]);
i--;
}
else if(nums[i]*nums[i]>nums[j]*nums[j]){
res.push_back(nums[j]*nums[j]);
j++;
}
}
return res;
}
my code 两头往中间
vector sortedSquares(vector& nums) {
vector res(nums.size(),0);
int start=0;
int end=nums.size()-1;
int idx=nums.size()-1;
while(start<=end){
if(nums[start]*nums[start]>nums[end]*nums[end]){
res[idx--]=nums[start]*nums[start];
start++;
}
else{
res[idx--]=nums[end]*nums[end];
end--;
}
}
return res;
}