488.祖玛游戏

https://leetcode-cn.com/problems/zuma-game/

dfs+剪枝+备忘录

class Solution:
    def findMinStep(self, board: str, hand: str) -> int:
        board = list(board)
        hand = list(hand)
        memo = {}

        def dfs(board, hand):
            #递归出口,为区分桌上的球消完还是手里的球用完,返回不同的值
            if not board:
                return 0
            if not hand:
                return -1
            res = -1
            #遍历手里每个球
            for j,h in enumerate(hand):
                hand.pop(j)
                #遍历桌上n个球构成的n+1个空隙,尝试插入每一个
                for i in range(len(board) + 1):
                    #多个相同,插最右边
                    if i + 1 < len(board) and board[i] == board[i+1] == h:
                        continue
                    board_copy = board[0:i] + [h] + board[i:]

                    l,r = i,i
                    boom=True   #能否消消乐
                    # 连锁反应,直到不能再消除
                    while boom and l >=0 and r < len(board_copy) and board_copy[l] == board_copy[r]:
                        #左右扩散
                        while l > 0 and board_copy[l-1] == board_copy[l]:
                            l-=1
                        while r +1 < len(board_copy)  and board_copy[r+1] == board_copy[r]:
                            r += 1
                        if r-l+1 >= 3:  #连续超过三就开始连锁消消乐(初始情况不会有连续三个,但经过消消乐之后可能会出现三个或以上连续的)
                            board_copy = board_copy[:l] + board_copy[r+1:]
                            boom = True
                            l -= 1
                            r = l
                        else:
                            boom = False
                    #dfs回溯+备忘录
                    rec = (tuple(board_copy), tuple(hand))  #当前board和hand作为备忘录key
                    #备忘录有记录则直接返回,否则dfs递归
                    if rec in memo:
                        res_dfs = memo[rec]
                    else:
                        res_dfs = dfs(board_copy, hand)
                        memo[rec] = res_dfs     #得到新结果写备忘录

                    if res_dfs != -1:   #不是球用完了
                        if res == -1:
                            res = res_dfs
                        elif res_dfs < res:
                            res = res_dfs
                #恢复现场
                hand.insert(j,h)
            return  res+1 if res != -1 else -1
        return dfs(board, hand)

最后更新于