★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(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
3 <= stones.length <= 10^4
1 <= stones[i] <= 10^9
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]
提示:
3 <= stones.length <= 10^4
1 <= stones[i] <= 10^9
stones[i]
的值各不相同。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
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 }