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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章