zoukankan      html  css  js  c++  java
  • LeetCode 1040 移动石子直到连续 II

    1040 移动石子直到连续 II

    模...本来想归类到模拟的, 看了看下面的标签还是放到滑动窗口好了

    • 最大移动次数

    选择一边的端点石子, 每次都移动到与原位置尽可能近的位置

    除了首次选择的起点, 剩余空位置的总会被填充一次石子

    由此可以得到最大值的公式, 用间距之和减去首尾较短的那段间距

    maxNum = sumGap - min(gap.front(), gap.back())
    
    • 最小移动次数

    从结果反推, 最终所有石子都会落在一个连续区间中

    为了移动次数最小, 区间外每个石子只移动一次就到达最终位置

    随着区间不断缩小, 最后区间的端点石子至少有一颗没有移动过

    此时稍微转换一下问题, 就能依靠原始石子的位置选择区间范围, 区间外的石子可视为自由石子, 最终目的为尽可能填充满区间(忽略细节)

    为了便于判断, 划分出2个我们需要的变量

    1. sum: 区间外的自由石子数, 可以用来自由移动
    2. gap: 区间内需要填充的空白位置数

    在不断变化区间(移动窗口)的过程中, 再划分区间改变的几个条件

    1. sum < gap: 自由石子数量小于空白位置, 需要额外移动一次端点石子, 完成移动需要的次数为sum + 1, 期望减小区间
    2. sum == gap: 自由石子数量等于空白位置, 完成移动需要的次数恰好为为sum, 期望移动区间
    3. sum > gap: 自由石子数量大于空白位置, 期望增大区间
    4. sum == 0: 自由石子数量不足, 期望减小区间

    要是不嫌烦的话, 还能对具体实现做一下优化...(懒癌发作)

    C艹

    class Solution {
    public:
        vector<int> numMovesStonesII(vector<int>& stones) {
            std::sort(stones.begin(), stones.end());
            int sumGap = (int)stones.back() - (int)stones.front() - (int)stones.size() + 1;
            for (int i = (int)stones.size()-1; i > 0; --i) stones[i] -= stones[i-1] + 1;
            stones.erase(stones.begin());
            int maxNum = sumGap - std::min(stones.front(), stones.back());
            
            int minNum = maxNum;
            for (int l = 0, r = 0, gapNum = stones[0]; r < stones.size();) {
                sumGap = (int)stones.size() - (r - l + 1);
                if (sumGap <= 0) {
                    gapNum -= stones[l++];
                    continue;
                }
                
                if (sumGap < gapNum) {
                    minNum = std::min(minNum, sumGap + 1);
                    gapNum -= stones[l++];
                    if (l > r) gapNum += stones[++r];
                } else if (sumGap == gapNum) {
                    minNum = std::min(minNum, sumGap);
                    gapNum -= stones[l++];
                    gapNum += stones[++r];
                } else {
                    gapNum += stones[++r];
                }
            }
            
            return {minNum, maxNum};
        }
    };
    
  • 相关阅读:
    C# 不用添加WebService引用,调用WebService方法
    贪心 & 动态规划
    trie树 讲解 (转载)
    poj 2151 Check the difficulty of problems (检查问题的难度)
    poj 2513 Colored Sticks 彩色棒
    poj1442 Black Box 栈和优先队列
    啦啦啦
    poj 1265 Area(pick定理)
    poj 2418 Hardwood Species (trie树)
    poj 1836 Alignment 排队
  • 原文地址:https://www.cnblogs.com/Simon-X/p/13624120.html
Copyright © 2011-2022 走看看