leetcode1040_移动石子直到连续||_滑动窗口

1. 这题出的真的乍一看到一点思路都没有.

2. 参考别人的题解才看出端倪.

3. 首先看最大移动次数是多少.因为只要我们将第一个数字stones[0]移动到stones[1]后,接下来就一定可以以间隔1按照剩下的缝隙填补,所以移动次数是stones[len-1]-stones[1]-len+2, 反过来从末尾往前看,移动次数是stones[len-2]-stones[0]-len+2, 因此最大移动次数是max(stones[len-1]-stones[1]-len+2, stones[len-2]-stones[0]-len+2).

4. 最小移动次数.因为最终的结果是将数字放在连续的数轴上,类似于大小为stones.size()的窗口,因此用滑动窗口的思路.每个窗口内的移动次数分别是stones.size()-(right-left+1).比较哪个最小即可.

5. 算最小次数时的一个特殊情况, 当类似[3,4,5,6,9]本身就连续时,最小次数是2, 3->8,9->7. 如果是[3,4,5,6,8]最小次数1,也不影响.甚至[3,4,5,6]本身就是连续,次数为0也不影响, 因为求的是最小次数.

class Solution {
public:
    vector<int> numMovesStonesII(vector<int>& stones) {
        sort(stones.begin(), stones.end());
        int left=0, right=0;
        int len = stones.size();
        vector<int> res(2);
        if(len<=2) return res; 
        int minV = INT_MAX;
        while(right<stones.size()) {
            while(stones[right]-stones[left]+1>len) left++;
            if(right-left+1==len-1 && stones[right]-stones[left]+1==len-1)
                minV = min(minV, 2);
            else minV = min(minV, len-(right-left+1));
            right++;
        }
        res[0] = minV;
        res[1] = max(stones[len-1]-stones[1]-len+2, stones[len-2]-stones[0]-len+2);
        return res;
    }
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值