力扣hot100-盛最多水的容器&移动零
·

刚看到这个题时就想,直接二重循环,秒了,hh,运行一下只通过58/65,超时了,代码如下::
class Solution {
public:
int maxArea(vector<int>& height) {
//暴力解
int max=0;
int length=height.size();
// for(int i=0;i<j;i++){
// for(int j=length-1;j>0;j--)
// }
for(int j=length-1;j>0;j--){
for(int i=0;i<j;i++){
int area=(j-i)*min(height[j],height[i]);
max=max>area?max:area;
}
}
return max;
}
};

然后后面又想,怎样缩小时间,我就想通过移动到最长的一个直线时停止,但是最坏时间复杂度还是O(n2),写了一下,还是超时,就换其他方法。
观察到,每次移动时,不一定非得一直移动左边或者右边,只移动最短的一条边即可,这样到最后的边界情况就是right==left.,此时,应该不会超时了,代码如下:
class Solution {
public:
int maxArea(vector<int>& height) {
int left=0,right=height.size()-1;
int max=0;
while(left<right){
int area=(right-left)*min(height[left],height[right]);
max=max>area?max:area;
if(height[left]>height[right]){
right--;
}
else{
left++;
}
}
return max;
}
};
通过了
后查看答案发现基本一样,意满离。
解题思路大概就是:
双指针法:使用两个指针,一个指向数组的起始位置(left),另一个指向数组的末尾位置(right)。
计算面积:计算当前两个指针所指向的线段与x轴构成的容器的面积,面积由较短的那条线的高度和两个指针之间的距离决定。
移动指针:为了寻找可能更大的面积,移动较短的那条线的指针向内侧移动一位,因为移动较长的线的指针不会增加容器的高度,而移动较短的线的指针有可能找到更高的线,从而增加面积。
更新最大面积:在每次移动指针后,计算新的面积,并更新最大面积。
重复步骤:重复上述过程,直到两个指针相遇。

依旧先暴力解答
class Solution {
public:
void moveZeroes(vector<int>& nums) {
//定义左右两个指针
int j=nums.size()-1;
for(int i=0;i<=j;){
if(nums[i]==0){
//i后面的元素循环左移
for(int k=i;k<nums.size()-1;k++){
nums[k]=nums[k+1];
}
nums[nums.size()-1]=0;
j--;
}
if(nums[i]==0){continue;}
else{i++;}
}
}
};
过了,时间要求没那么高,想办法优化一下,参考上面的那道题,不过尝试左右指针初始时都为0.
也就是left=0,right=0

代码如下:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int length = nums.size(), left = 0, right = 0;
while (right < length) {
if (nums[right]) { //非零时
swap(nums[left], nums[right]);
left++;
}
right++;
}
}
};
更多推荐



所有评论(0)