283.移动零
题目
感觉双指针就是为了优化掉一层循环的,本题外层进行遍历i,内层j是从i+1到n的,
另一个思路是不必要每次都交换相邻的,而是当i为0时,用j找到第一个不为0的与i进行交换,然后i继续往后,j也继续往后,有点像简单选择排序算法???遇到问题可以先暴力,然后想怎么优化
我的思路:
i指向0,j指向非0,i和j之间都是0
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int i=0;
while(i<nums.size())
{
if(nums[i]!=0)
{
i++;
}
else
{
break;
}
}
for(int j=i+1;j<nums.size();j++)
{
if(nums[j]!=0)
{
swap(nums[i++],nums[j]);
}
}
}
};
官方
思路一样,但是写的精简了,我是先找到第一个i为0的,意思就是不是0,i和j一直同时加,如果是0,那么j一直加
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int n = nums.size(), left = 0, right = 0;
while (right < n) {
if (nums[right]) {
swap(nums[left], nums[right]);
left++;
}
right++;
}
}
};
42.接雨水
题目
我的思路:
每次找到后一个比自己高的柱子,求出体积减去中间部分的柱子体积,错误的原因,没有考虑周到,只是看着图形想的,但是有可能第一个高,右边遍历就得找比它低的,而我只找到比它高的。正确的思想应该找到一个通用的公式,判断每一个第i个柱子接的雨水,而不是根据图形的个例来设计算法。
class Solution {
public:
int trap(vector<int>& height) {
int n=height.size();
int res=0;
for(int left=0;left<n;left++)
{
int right=left+1;
int midsum=0;
while(right<n&&height[right]<height[left])
{
right++;
midsum+=height[right];
}
if(right<n)
{
res+=(right-left)*min(height[right],height[left])-midsum;
}
}
return res;
}
};
官方:
方法一:动态规划,但是我没搞明白为啥是动态规划?难道只要找到一个通用公式都算是动态规划?
class Solution {
public:
int trap(vector<int>& height) {
int n=height.size();
int res=0;
vector<int> leftMax(n); //注意这里初始化
vector<int> rightMax(n);
leftMax[0]=height[0];//这里也初始化
for(int i=1;i<n;i++)
{
leftMax[i]=max(leftMax[i-1],height[i]);
}
rightMax[n-1]=height[n-1];
for(int i=n-2;i>=0;i--) //倒着往前从n-2开始的,而不是从0开始
{
rightMax[i]=max(rightMax[i+1],height[i]);
}
for(int i=0;i<n;i++)
{
res+=min(leftMax[i],rightMax[i])-height[i];
}
return res;
}
};
方法二:单调栈
方法三:双指针
都没看/。。。。。。。。