• 边工作边刷题:70天一遍leetcode: day 66


    Word Search II

    要点:

    • board作为visited。为什么dfs最后要unset visited?visited的意义是在当前的dfs stack内,对这题也就是当前path。下一层dfs之后,当前path结果已经得到,但是改点还可能在其他的path上,所以要把visited unset。类似于有向图dfs。
    • trie: 一个buildtrie function即可。search和dfs是一起的。
    • trie和层次:当前node是当前处理字符的前一个点,所以进入dfs才开始处理当前字符(or board[i][j]),否则会出现["a"], dict=["a”]返回[]的错误。

    错误点:

    • 类似grid渲染,每个点都可能是起点,所以要loop每个点然后dfs
    • 简单dedup:当找到一个词以后,将isLeaf设为False。(7/8/16) 优化 1:直接用word or None表示leaf,这样不用在dfs中记录path和最后重构单词。
    • 优化2:每层dfs call之前做边界检查,省了function call的cost:从TLE提高到beat 8%
    • 优化3:用map记录每个结点的neighbors而不是用[]*26,从8%提高到beat 50.75%
    • 优化4:直接把board size m, n pass in,而不是on-the-fly计算,从50.75% => 73.88%
    class Solution(object):
        class TrieNode:
            def __init__(self):
                # self.isLeaf = False
                # self.neighbors = [None]*26
                self.neighbors = {} # use map instead of list*26 from 8% to 50.75%
                self.word = None
    
        @staticmethod
        def buildDict(words):
            root = Solution.TrieNode()
            for w in words:
                cur = root
                #for i in xrange(len(w)):
                for c in w:
                    # c = ord(w[i])-ord('a')
                    # if not cur.neighbors[c]:
                    #     cur.neighbors[c]=Solution.TrieNode()
                    cur = cur.neighbors.setdefault(c, Solution.TrieNode())
                    # cur=cur.neighbors[c]
                cur.word = w # optimal 2: root.word is not the TLE cause
            return root
    
        def findWords(self, board, words):
            """
            :type board: List[List[str]]
            :type words: List[str]
            :rtype: List[str]
            """
            def dfs(board, i, j, root, solutions, m, n):
                # m = len(board)
                # n = len(board[0])
                # print i,j
                
                c = board[i][j]
                if not (c and c in root.neighbors):
                    return
                
                board[i][j], root = None, root.neighbors[c]
                
                if root.word:
                    solutions.append(root.word)
                    root.word = None
                
                # if i>=m or j>=n or i<0 or j<0:
                #   return
                
                # c = board[i][j]
                #print c
                #if board[i][j]!='#' and root.neighbors[ord(c)-ord('a')]:
                #    rn = root.neighbors[ord(c)-ord('a')]
                    # resw.append(board[i][j])
                #    board[i][j]='#'
                if i+1<m: # optimal 1: check before funciton call beat 8%
                    dfs(board, i+1, j, root, solutions, m, n)
                if i-1>=0:
                    dfs(board, i-1, j, root, solutions, m, n)
                if j+1<n:
                    dfs(board, i, j+1, root, solutions, m, n)
                if j-1>=0:
                    dfs(board, i, j-1, root, solutions, m, n)
                #     # resw.pop()
                # for x, y in ((0, -1), (-1, 0), (0, 1), (1, 0)):
                #     ii, jj = i + x, j + y
                #     if 0 <= ii < m and 0 <= jj < n:
                #         dfs(board, ii, jj, root, solutions)
                board[i][j]=c
            
            root = Solution.buildDict(words)
            solutions = []
            # resw = []
            m = len(board)
            n = len(board[0])
            for i in xrange(m):
                for j in xrange(n):
                    dfs(board, i, j, root, solutions, m, n)
            return solutions
                
    
  • 相关阅读:
    最近有点烦
    好累啊
    几招有效防电脑辐射
    发两张搞笑图片
    几招有效防电脑辐射
    English Study
    人脸识别方法(转载)
    小常识
    23、C++ Primer 4th 笔记,面向对象编程(1)
    18、C++ Primer 4th 笔记,复制控制
  • 原文地址:https://www.cnblogs.com/absolute/p/5690349.html
Copyright © 2020-2023  润新知