JobHopper-WordSearchII

找到了之前的Java 版本

转化成python,LC提交后有一个例子超时未通过,但是在PyCharm里运行了,没有问题,答案正确。看了其他人提交的 python solution 都是类似的解法。

high-level 理解:

1. Trie 就是 为了多词搜索的高效DS,词的开始都是 root node,词的结尾 有endWork 做标记,从 root 到 标记的 path,就是一个单词

2. 有了Trie, board 上就是 从每个 cell,每次一个cell 一个 char 的比较。Order 和 Trie level 是一一对应的

3. 题目中一些特别关键的要求:(1) 同一个词不能 回溯搜索 --> 所以要 在 board 上 mark visited,unmark visited; (2) code, coder, coded, 不属于上述情况,而是 "code" 找到后,相邻的cell 有 'r' 或 'd',可以继续搜索; (3) 为了解决同词多次出现的情况,一旦 这个词 被选中后,就把 Trie 把 endWord set to None.  

几个要点,也是出bug的地方

1. build trie 时,curr = root 在每一个词开始

2. mark and unmark cells in board

3. trick, 为了去重,在 Trie 中 set endWord as None after the 1st match.

class TrieNode(object):
    def __init__(self):
        self.endWord = None
        self.next = [None] * 26


class Solution:
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        root = self.buildTrie(words)

        res: list[str] = []
        m = len(board)
        n = len(board[0])
        for i in range(m):
            for j in range(n):
                # deepcopy = copy.deepcopy(board)
                # print("deep copy of board:")
                # for row in deepcopy:
                #     print(row)
                # print("")
                self.dfs(i, j, board, root, res)
        return res

    def dfs(self, i: int, j: int, board, node: TrieNode, res: List[str]):
        m = len(board)
        n = len(board[0])
        if i < 0 or i >= m or j < 0 or j >= n:
            return

        letter = board[i][j]
        # check if the cell visited
        if letter == "#":
            return

        # check if the letter matches any word at the right level
        # the order of the letter in the world should be same as the level in the trie.
        idx = ord(letter) - ord("a")
        if node.next[idx] is None:
            return

        # Now the letter matches, ready to go to the next letter
        # Mark the cell as visited
        board[i][j] = "#"

        # let's check if there is a endWord marker, in the next node
        # For the reason why the letter in the next node, see how the trie is constructed.
        curr = node.next[idx]
        if curr.endWord is not None:
            res.append(curr.endWord)

        self.dfs(i + 1, j, board, curr, res)
        self.dfs(i - 1, j, board, curr, res)
        self.dfs(i, j + 1, board, curr, res)
        self.dfs(i, j - 1, board, curr, res)

        board[i][j] = letter
        return

    def buildTrie(self, words):
        root = TrieNode()
        # This is the bug!!!
        curr = root

        for word in words:
            curr = root
            for letter in word:
                idx = ord(letter) - ord('a')
                if curr.next[idx] is None:
                    curr.next[idx] = TrieNode()
                curr = curr.next[idx]
            curr.endWord = word

        return root
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值