https://leetcode-cn.com/probl...前端
回憶一下祖瑪遊戲。如今桌上有一串球,顏色有紅色(R),黃色(Y),藍色(B),綠色(G),還有白色(W)。 如今你手裏也有幾個球。 每一次,你能夠從手裏的球選一個,而後把這個球插入到一串球中的某個位置上(包括最左端,最右端)。接着,若是有出現三個或者三個以上顏色相同的球相連的話,就把它們移除掉。重複這一步驟直到桌上全部的球都被移除。 找到插入並能夠移除掉桌上全部球所需的最少的球數。若是不能移除桌上全部的球,輸出 -1 。 示例: 輸入: "WRRBBW", "RB" 輸出: -1 解釋: WRRBBW -> WRR[R]BBW -> WBBW -> WBB[B]W -> WW (翻譯者標註:手上球已經用完,桌上還剩兩個球沒法消除,返回-1) 輸入: "WWRRBBWW", "WRBRW" 輸出: 2 解釋: WWRRBBWW -> WWRR[R]BBWW -> WWBBWW -> WWBB[B]WW -> WWWW -> empty 輸入:"G", "GGGGG" 輸出: 2 解釋: G -> G[G] -> GG[G] -> empty 輸入: "RBYYBBRRB", "YRBGB" 輸出: 3 解釋: RBYYBBRRB -> RBYY[Y]BBRRB -> RBBBRRB -> RRRB -> B -> B[B] -> BB[B] -> empty 標註: 你能夠假設桌上一開始的球中,不會有三個及三個以上顏色相同且連着的球。 桌上的球不會超過20個,輸入的數據中表明這些球的字符串的名字是 "board" 。 你手中的球不會超過5個,輸入的數據中表明這些球的字符串的名字是 "hand"。 輸入的兩個字符串均爲非空字符串,且只包含字符 'R','Y','B','G','W'。
面試題困難難度的題目常見的題型有:python
本題就是遊戲類題目。 若是你是一個前端, 說不定還會考察你如何實現一個 zuma 遊戲。這種遊戲類的題目,能夠簡單能夠困難, 好比力扣經典的石子游戲,寶石遊戲等。這類題目沒有固定的解法。我作這種題目的思路就是先暴力模擬,再嘗試優化算法瓶頸。git
注意下數據範圍球的數目 <= 5,所以暴力法就變得可行。基本思路是暴力枚舉手上的球能夠消除的地方, 咱們可使用回溯法來完成暴力枚舉的過程,在回溯過程記錄最小值便可。因爲回溯樹的深度不會超過 5,所以這種解法應該能夠 AC。github
上面提到的能夠消除的地方
,指的是連續相同顏色 + 手上相同顏色的球大於等於 3,這也是題目說明的消除條件。面試
所以咱們只須要兩個指針記錄連續相同顏色球的位置,若是能夠消除,消除便可。算法
如圖,咱們記錄了連續紅球的位置, 若是手上有紅球, 則能夠嘗試將其清除,這一次決策就是回溯樹(決策樹)的一個分支。以後咱們會撤回到這個決策分支, 嘗試其餘可行的決策分支。優化
以 board = RRBBRR , hand 爲 RRBB 爲例,其決策樹爲:spa
其中虛線表示無需手動干預,系統自動消除。葉子節點末尾的黃色表示所有消除須要的手球個數。路徑上的文字後面的數字表示這次消除須要的手球個數翻譯
若是你對回溯不熟悉,能夠參考下我以前寫的幾篇題解:好比 46.permutations。
能夠看出, 若是選擇先消除中間的藍色,則只須要一步便可完成。設計
關於計算連續球位置的核心代碼(Python3):
i = 0 while i < len(board): j = i + 1 while j < len(board) and board[i] == board[j]: j += 1 # 其餘邏輯 # 更新左指針 i = j
具體算法:
2.1 確承認以消除的位置,算法參考上面的代碼。
2.2 判斷手上是否有足夠相同顏色的球能夠消除。
2.3 回溯的過程記錄全局最小值。
代碼支持:Python3
Python3 Code:
class Solution: def findMinStep(self, board: str, hand: str) -> int: def backtrack(board): if not board: return 0 i = 0 ans = 6 while i < len(board): j = i + 1 while j < len(board) and board[i] == board[j]: j += 1 balls = 3 - (j - i) if counter[board[i]] >= balls: balls = max(0, balls) counter[board[i]] -= balls ans = min(ans, balls + backtrack(board[:i] + board[j:])) counter[board[i]] += balls i = j return ans counter = collections.Counter(hand) ans = backtrack(board) return -1 if ans > 5 else ans
複雜度分析
你們對此有何見解,歡迎給我留言,我有時間都會一一查看回答。更多算法套路能夠訪問個人 LeetCode 題解倉庫:https://github.com/azl3979858... 。 目前已經 36K star 啦。你們也能夠關注個人公衆號《力扣加加》帶你啃下算法這塊硬骨頭。