移动零
思路:记录前面有多少个0,然后后面遇到非0值,就把它向前移动多少位
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int cnt = 0;
for(int i=0; i<nums.size(); i++)
{
if(nums[i] == 0) cnt++;
else
{
nums[i-cnt] = nums[i];
}
}
for(int i=nums.size()-cnt; i<nums.size(); i++)
nums[i] = 0;
}
};
盛最多水的容器
思路:双指针,每次只移动较低值的边界,即可一定找到最优解
class Solution {
public:
int maxArea(vector<int>& height) {
int ans = 0;
int l = 0, r = height.size()-1;
while(l < r)
{
ans = max(ans, min(height[l], height[r]) * (r-l));
if(height[l] < height[r]) l++;
else r--;
}
return ans;
}
};
三数之和
思路一:每次只枚举前两个数,然后后面一个数字用双指针优化
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans;
sort(nums.begin(), nums.end());
for(int first=0; first<nums.size()-2; first++)
{
//去重
if(first > 0 && nums[first] == nums[first-1]) continue;
int third = nums.size()-1;
for(int second = first+1; second < nums.size()-1; second++)
{
//去重
if(second >first+1 && nums[second] == nums[second-1]) continue;
while(nums[second] + nums[third] > -nums[first] && second < third) third--;
if(nums[second] + nums[third] + nums[first] == 0 && second < third)
{
ans.push_back({nums[first], nums[second], nums[third]});
}
}
}
return ans;
}
};
接雨水
思路:每个格子能接水的高度,取决于其左右的最高高度的较小值
class Solution {
public:
int l[30000], r[30000];
int trap(vector<int>& height) {
for(int i=0; i<height.size(); i++)
{
if(!i) l[i] = height[i];
else l[i] = max(l[i-1], height[i]);
}
for(int i=height.size()-1; i>=0; i--)
{
if(i == height.size()-1) r[i] = height[i];
else r[i] = max(r[i+1], height[i]);
}
int ans = 0 ;
for(int i=1; i<height.size()-1; i++)
{
int t = min(l[i-1], r[i+1]) - height[i];
if(t > 0) ans += t;
}
return ans;
}
};