【滑窗】B019_LC_移動石子直到連續 II(分類討論)

一、Problem

在一個長度無限的數軸上,第 i 顆石子的位置爲 stones[i]。如果一顆石子的位置最小/最大,那麼該石子被稱作端點石子。

每個回合,你可以將一顆端點石子拿起並移動到一個未佔用的位置,使得該石子不再是一顆端點石子。

值得注意的是,如果石子像 stones = [1,2,5] 這樣,你將無法移動位於位置 5 的端點石子,因爲無論將它移動到任何位置(例如 0 或 3),該石子都仍然會是端點石子。

當你無法進行任何移動時,即,這些石子的位置連續時,遊戲結束。

要使遊戲結束,你可以執行的最小和最大移動次數分別是多少? 以長度爲 2 的數組形式返回答案:answer = [minimum_moves, maximum_moves] 。

示例 1:
輸入:[7,4,9]
輸出:[1,2]
解釋:
我們可以移動一次,4 -> 8,遊戲結束。
或者,我們可以移動兩次 9 -> 5,4 -> 6,遊戲結束。

示例 2
輸入:[6,5,4,3,10]
輸出:[2,3]
解釋:
我們可以移動 3 -> 8,接着是 10 -> 7,遊戲結束。
或者,我們可以移動 3 -> 7, 4 -> 8, 5 -> 9,遊戲結束。
注意,我們無法進行 10 -> 2 這樣的移動來結束遊戲,因爲這是不合要求的移動。

提示:

3 <= stones.length <= 10^4
1 <= stones[i] <= 10^9
stones[i] 的值各不相同。

二、Solution

方法一:雙指針

分類討論一下:

  • 最大移動次數:
    A = [1,5,7,10,13]
    1,x,x,x,x,5,x,7,x,x,10,x,x,13
    (1)要麼我們把第一塊石頭挪到其後面的 x 處,最大距離爲:A[n-1]-A[1]-n+2
    (2)要麼我們把最後一塊石頭挪到其前面的 x 處,最大距離爲:A[n-2]-A[0]-n+2
    		// 注:這個(-n+2)是要減去中間被佔用的位置
    
  • 最小移動次數
    (1) 這種情況只能讓第1塊石頭先移動到6號位置,然後讓最後一塊石頭移動到第5個位置,總共2步
    A = [1,2,3,4,7]
    1,2,3,4,x,x,7
    (2) 這種情況只需按部就班地講位1石子移到5號位置,然後將位3石子移到4號位置,總共n-k步(k爲窗口內部的石子數)
    A = [1,x,3,x,x,6]
    
class Solution {
    public int[] numMovesStonesII(int[] A) {
        Arrays.sort(A);
        int n = A.length, l = 0, r = 0, mi = 0x3f3f3f3f, mx = Math.max(A[n-1]-A[1]-n+2, A[n-2]-A[0]-n+2);

        while (r < n) {
        	while (A[r] - A[l] >= n) 
        		l++;
            int cur = r-l+1;
        	if (cur == n-1 && A[r]-A[l]+1 == n-1) //如果窗口內部有n-1個石子,且n-1個石子是連續的
        		mi = 2;
        	else 
        		mi = Math.min(mi, n-cur);
            r++;
        }
        return new int[]{mi, mx};
    }
}

複雜度分析

  • 時間複雜度:O(n)O(n)
  • 空間複雜度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章