leetcode100双指针

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;
        
    }
};

方法二:单调栈
方法三:双指针
都没看/。。。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值