题目要求在保持非零数顺序情况下,把所有零移到末尾。那么即可用双指针,r指针每次遇到非零数,与l指针进行交换,然后移动l指针,直到r走完。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int l=0,r=0;
int n=nums.size();
while(r<n){
if(nums[r]){
swap(nums[l],nums[r]);
l++;
}
r++;
}
}
};
盛水量的多少由两边高度的较小值与宽度的乘积决定,所以要维护一个ans对指针变化后的值进行更新。然后使用双指针,每次移动的指针肯定是矮的一端,才能保证之后更新的结果可能更大。
class Solution {
public:
int maxArea(vector<int>& height) {
int l=0,r=height.size()-1;
int ans=0;
while(l<r){
int area=min(height[l],height[r])*(r-l);
ans=max(ans,area);
if(height[l]<height[r]){
l++;
}else{
r--;
}
}
return ans;
}
};
排序后,对于每一个nums[i],只需对其后面的数字判断是否存在三者相加为0即可。由于单调性,双指针从两端向中间移动,更新答案。要注意的是每一个nums[i]不能等于nums[i-1],否则会重复计算结果。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n=nums.size();
sort(nums.begin(),nums.end());
vector<vector<int>>ans;
for(int i=0;i<n-2;i++){
int x=nums[i];
if(i&&x==nums[i-1])continue;
if(x+nums[i+1]+nums[i+2]>0){
break;
}
if(x+nums[n-1]+nums[n-2]<0)continue;
int j=i+1,k=n-1;
while(j<k){
int s=x+nums[j]+nums[k];
if(s>0){
k--;
}else if(s<0){
j++;
}else{
ans.push_back({x,nums[j],nums[k]});
for(j++;j<k&&nums[j]==nums[j-1];j++);
for(k--;j<k&&nums[k]==nums[k+1];k--);
}
}
}
return ans;
}
};
对于所接的雨水,由两端最高高度的较小值决定,可以分为多个小段,每一段的水等于两端较小值减去height[i],哪边最高高度较小先结算哪一边。
class Solution {
public:
int trap(vector<int>& height) {
int n=height.size();
int l=0,r=n-1,ans=0,l_m=0,r_m=0;
while(l<r){
l_m=max(l_m,height[l]);
r_m=max(r_m,height[r]);
if(l_m<r_m){
ans+=l_m-height[l++];
}else{
ans+=r_m-height[r--];
}
}
return ans;
}
};