[Swift]LeetCode1040. 移動石子直到連續 II | Moving Stones Until Consecutive II

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-calkssyt-mc.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

On an infinite number line, the position of the i-th stone is given by stones[i].  Call a stone an endpoint stone if it has the smallest or largest position.git

Each turn, you pick up an endpoint stone and move it to an unoccupied position so that it is no longer an endpoint stone.github

In particular, if the stones are at say, stones = [1,2,5], you cannotmove the endpoint stone at position 5, since moving it to any position (such as 0, or 3) will still keep that stone as an endpoint stone.數組

The game ends when you cannot make any more moves, ie. the stones are in consecutive positions.微信

When the game ends, what is the minimum and maximum number of moves that you could have made?  Return the answer as an length 2 array: answer = [minimum_moves, maximum_moves]app

Example 1:spa

Input: [7,4,9]
Output: [1,2] Explanation: We can move 4 -> 8 for one move to finish the game. Or, we can move 9 -> 5, 4 -> 6 for two moves to finish the game. 

Example 2:code

Input: [6,5,4,3,10]
Output: [2,3] We can move 3 -> 8 then 10 -> 7 to finish the game. Or, we can move 3 -> 7, 4 -> 8, 5 -> 9 to finish the game. Notice we cannot move 10 -> 2 to finish the game, because that would be an illegal move. 

Example 3:htm

Input: [100,101,104,102,103]
Output: [0,0]

Note:blog

  1. 3 <= stones.length <= 10^4
  2. 1 <= stones[i] <= 10^9
  3. stones[i] have distinct values.

在一個長度無限的數軸上,第 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:

輸入:[100,101,104,102,103]
輸出:[0,0]

提示:

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

144ms
 1 class Solution {
 2     func numMovesStonesII(_ stones: [Int]) -> [Int] {                        
 3         let n = stones.count, sortStones = stones.sorted()
 4         var maxcontinuous = 1, end = 0, j = 0
 5         var si = 0, ei = 0
 6         for i in 0..<n {
 7             end = sortStones[i] + n
 8             while j < n && sortStones[j] < end { j += 1 }
 9 
10             if j - i > maxcontinuous || (j - i == maxcontinuous && sortStones[j-1] - sortStones[i] > ei - si ) {
11                 si = sortStones[i]
12                 ei = sortStones[j-1]
13                 maxcontinuous = j-i
14             }
15         }
16 
17         var minimum = n - maxcontinuous
18         if maxcontinuous == n-1 && ei-si == maxcontinuous-1 { minimum += 1 }
19         if maxcontinuous == n { minimum = 0 }
20         let largest_interval = max(sortStones[n-1] - sortStones[1], sortStones[n-2] - sortStones[0]) - 1
21         let maximum = largest_interval - ( n - 3)
22         return [minimum, maximum]
23     }
24 }

160ms

 1 class Solution {
 2     private var stones: [Int] = []
 3     
 4     func numMovesStonesII(_ stones: [Int]) -> [Int] {
 5         self.stones = stones.sorted()
 6         return [findMin(), findMax()]
 7     }
 8     
 9     private func findMax() -> Int {
10         var count = 0
11         var last: Int = stones[0]
12         
13         for i in 1..<(stones.count - 1) {
14             count += stones[i] - last - 1
15             last = stones[i]
16         }
17         
18         var result = count
19         
20         count = 0
21         last = stones[1]
22         for i in 2..<stones.count {
23             count += stones[i] - last - 1
24             last = stones[i]
25         }
26         
27         result = max(result, count)
28         
29         return result
30     }
31     
32     private func findMin() -> Int {
33         var window = (left: 0, right: 1)
34         var minMoves = Int.max
35         
36         while true {
37             let windowSpan = stones[window.right] - stones[window.left] + 1
38             let windowSize = window.right - window.left + 1
39             if windowSpan <= stones.count {
40                 if windowSpan == windowSize && windowSize == stones.count - 1 {
41                     if stones[stones.count - 1] - stones[0] == stones.count - 1 {
42                         return 0
43                     } else {
44                         if window.left == 1 {
45                             return stones[1] - stones[0] == 2 ? 1 : 2
46                         } else {
47                             return stones[stones.count - 1] - stones[window.right] == 2 ? 1 : 2
48                         }
49                     }
50                 }
51                 
52                 minMoves = min(minMoves, stones.count - (window.right - window.left + 1))
53                 if window.right != stones.count - 1 {
54                     window.right += 1
55                 } else {
56                     break
57                 }
58             } else {
59                 window.left += 1
60             }
61         }
62         
63         return minMoves
64     }
65 }

Runtime: 192 ms

Memory Usage: 19.6 MB
 1 class Solution {
 2     func numMovesStonesII(_ stones: [Int]) -> [Int] {
 3         var stones = stones.sorted(by:<)
 4         var mx:Int = 0
 5         var n:Int = stones.count
 6         for i in 1..<n
 7         {
 8             mx += stones[i] - stones[i - 1] - 1
 9         }
10         if mx == 0 {return [0,0]}
11         mx -= min(stones[1] - stones[0] - 1, stones[n - 1] - stones[n - 2] - 1)
12         var res:Int = 0
13         if (stones[n - 2] - stones[0] == n - 2 && stones[n - 1] - stones[n - 2] > 2) || (stones[n - 1] - stones[1] == n - 2 && stones[1] - stones[0] > 2)
14         {
15             return [2, mx]
16         }
17         else
18         {
19             var dq:[Int] = [Int]()
20             for stone in stones
21             {
22                 dq.append(stone)
23                 while(dq.last! - dq.first! + 1 > n)
24                 {
25                     dq.removeFirst()
26                 }
27                 res = max(res, dq.count)
28             }
29         }        
30         return [n - res, mx]
31     }
32 }
相關文章
相關標籤/搜索