我们还有更长的路要走,不过没关系,道路就是生活。
前言
这是我自己刷算法题的第一篇博客总结。后期我会继续把刷算法题的笔记开源至博客上。
技巧
1. 双指针算法,实际上是利用数组下标来充当指针,并不是直接使用指针。
2. cur指针,扫描遍历指针,左边是已经扫描遍历的部分,中间及右边是还未扫描遍历的部分。
3. dest指针,分隔指针,左边是已经排序的部分,中间及右边是还未排序的部分。
4. 划分为三个区间:[0,dest-1],[dest,cur-1],[cur,n-1]。
5. 双指针算法分为两类:就地操作和异地操作。
6. 就地操作不需要重新创建一个数组,但是需要考虑覆盖问题。异地操作需要重新创建一个数组,但是不需要考虑覆盖问题。
7. 双指针算法可以从前往后遍历,又可以从后往前遍历。
8. 双指针算法可以变形为快慢指针,一个移动快的指针,一个移动慢的指针。
9. 双指针算法可以变形为相撞指针,两个指针相向而行,最终走到一起,共同遍历数组。
10. 双指针算法可以变形为相向指针,需要先排序,然后利用单调性,两个指针从两端向对立端移动,从而实现不重不漏。
例题
1. leetcode-283题: 283. 移动零 - 力扣(LeetCode)
https://leetcode.cn/problems/move-zeroes/
class Solution {
public:
void moveZeroes(vector<int>& nums)
{
int cur=0,dest=0;
while(cur<nums.size())
{
if(nums[cur]==0)
cur++;
else
{
swap(nums[cur],nums[dest]);
cur++;
dest++;
}
}
}
};
2. leetcode-1089题: 1089. 复写零 - 力扣(LeetCode)
https://leetcode.cn/problems/duplicate-zeros/
class Solution {
public:
void duplicateZeros(vector<int>& arr)
{
int cur=0,dest=0;
while(dest<arr.size())
{
if(arr[cur]!=0)
{
cur++;
dest++;
}
else
{
cur++;
dest+=2;
}
}
if(dest>arr.size())
{
dest=arr.size()-1;
arr[dest]=0;
cur-=2;
dest--;
while(cur>=0)
{
if(arr[cur]!=0)
{
arr[dest]=arr[cur];
dest--;
cur--;
}
else
{
arr[dest]=0;
arr[dest-1]=0;
dest-=2;
cur--;
}
}
}
else
{
dest=arr.size()-1;
cur--;
while(cur>=0)
{
if(arr[cur]!=0)
{
arr[dest]=arr[cur];
dest--;
cur--;
}
else
{
arr[dest]=0;
arr[dest-1]=0;
dest-=2;
cur--;
}
}
}
}
};
3. leetcode-208题:
class Solution {
public:
int Add(int n)
{
int sum=0;
while(n>0)
{
sum+=(n%10)*(n%10);
n=n/10;
}
return sum;
}
bool isHappy(int n)
{
int fast=Add(n),slow=n;
while(fast!=slow)
{
fast=Add(Add(fast));
slow=Add(slow);
}
if(fast==1)
return true;
else
return false;
}
};
4. leetcode-11题:
class Solution {
public:
int maxArea(vector<int>& height)
{
int left=0,right=height.size()-1;
int max_size=0,cur_size=0;
while(left<right)
{
cur_size=(int)(right-left)*(min(height[left],height[right]));
max_size=max(cur_size,max_size);
if(height[left]<height[right])
left++;
else
right--;
}
return max_size;
}
};
5. leetcode-611题:
class Solution
{
public:
int triangleNumber(vector<int>& nums)
{
int ret=0;
sort(nums.begin(),nums.end());
for(int last=nums.size()-1;last>1;last--)
{
int left=0,right=last-1;
while(left<right)
{
while(nums[right]+nums[right-1]>nums[last])
{
if(nums[left]+nums[right]>nums[last])
{
ret=ret+(right-left);
break;
}
else
{
left++;
}
}
right--;
}
}
return ret;
}
};
6. leetcode-179题:
class Solution {
public:
vector<int> twoSum(vector<int>& price, int target)
{
int left=0,right=price.size()-1;
while(price[left]+price[right]!=target)
{
if(price[left]+price[right]<target)
left++;
else
right--;
}
vector<int> v;
v.push_back(price[left]);
v.push_back(price[right]);
return v;
}
};
7. leetcode-15题:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums)
{
vector<vector<int>> set;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();)
{
if(nums[i]>0)
{
break;
}
int left=i+1,right=nums.size()-1,target=-nums[i];
while(left<right)
{
if(nums[left]+nums[right]<target)
{
left++;
}
else if(nums[left]+nums[right]>target)
{
right--;
}
else
{
set.push_back({nums[i],nums[left],nums[right]});
left++,right--;
while(left<right&&nums[left]==nums[left-1])
{
left++;
}
while(left<right&&nums[right]==nums[right+1])
{
right--;
}
}
}
i++;
while(i<nums.size()&&nums[i]==nums[i-1])
{
i++;
}
}
return set;
}
};
8. leetcode-18题:
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target)
{
sort(nums.begin(),nums.end());
vector<vector<int>> set;
if(nums.size()<4)
{
return set;
}
int first=0;
while(first<nums.size()-3)
{
int second=first+1;
while(second<nums.size()-2)
{
int left=second+1,right=nums.size()-1;
long long tar=(long long)target-nums[first]-nums[second];
while(left<right)
{
if(nums[left]+nums[right]<tar)
{
left++;
}
else if(nums[left]+nums[right]>tar)
{
right--;
}
else
{
set.push_back({nums[first],nums[second],nums[left],nums[right]});
left++;
right--;
while(left<right&&nums[left]==nums[left-1])
{
left++;
}
while(left<right&&nums[right]==nums[right+1])
{
right--;
}
}
}
second++;
while(second<nums.size()-2&&nums[second]==nums[second-1])
{
second++;
}
}
first++;
while(first<nums.size()-3&&nums[first]==nums[first-1])
{
first++;
}
}
return set;
}
};
致谢
感谢您花时间阅读这篇文章!如果您对本文有任何疑问、建议或是想要分享您的看法,请不要犹豫,在评论区留下您的宝贵意见。每一次互动都是我前进的动力,您的支持是我最大的鼓励。期待与您的交流,让我们共同成长,探索技术世界的无限可能!