Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

79 Word Search #71

Open
tech-cow opened this issue Oct 13, 2019 · 3 comments
Open

79 Word Search #71

tech-cow opened this issue Oct 13, 2019 · 3 comments

Comments

@tech-cow
Copy link
Owner

tech-cow commented Oct 13, 2019

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example:

board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]

Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.

@tech-cow tech-cow created this issue from a note in 刷题板 (Coding) Oct 13, 2019
@tech-cow
Copy link
Owner Author

第一次刷

  1. 常犯错:Parameter Passing的时候经常忘记加东西
  2. 是len(board) 而不是 len(word), 再有多个参考参数的时候,要注意分辨。。
  3. 最好不要用slice
class Solution(object):
    def exist(self, board, word):
        if not board: return False   # No need
        
        for i in range(len(board)):
            for j in range(len(board[0])):
                if self.dfsHelper(board, i , j, word):
                    return True
        return False
    
    
    def dfsHelper(self, board, i, j, word):  # frequent bug: 经常没有match这个
        if len(word) == 0: return True
        
        if i < 0 or i >= len(word) or j < 0 or j >= len(word[0]) or word[0] != board[i][j]:  # bug wtf: len(word????)
            return False
        
        word = board[i][j]
        
        board[i][j] = '#'
        
        found = \
        self.dfsHelper(board, i - 1, j, word[1:]) or \    # Slicing是个Bad Idea,太多空间损耗,应该直接同index
        self.dfsHelper(board, i + 1, j, word[1:]) or \
        self.dfsHelper(board, i, j - 1, word[1:]) or \
        self.dfsHelper(board, i, j + 1, word[1:])
        
        board[i][j] = word
        return found

@tech-cow
Copy link
Owner Author

tech-cow commented Oct 13, 2019

Working Code (使用Visited)

这里学到一招记录二维数组里面的Visited Elements: 这种方式消费了额外空间,但是不对原Input board进行修改。

时间复杂度

image

遍历所有的元素需要 m * n, 在每个元素使用一次DFS, 有4个方向(对应Recursion Tree里面的4个Branches,然后树的高度为k)

所以总共 O(m * n * 4^k)

class Solution(object):
    def exist(self, board, word):
        visited = {}
        
        for i in range(len(board)):
            for j in range(len(board[0])):
                if self.dfsHelper(board, i , j, visited, word, 0):
                    return True
        return False
                
                
    
    def dfsHelper(self, board, i , j, visited, word, wordIndex):
        '''
        rType: True/False -> Boolean
        '''
        
        if wordIndex == len(word):
            return True
        
        if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or word[wordIndex] != board[i][j] or visited.get((i, j)):
            return False
        
        visited[(i, j)] = True
        
        found = self.dfsHelper(board, i + 1, j, visited, word, wordIndex + 1) \
                or self.dfsHelper(board, i - 1, j, visited, word, wordIndex + 1) \
                or self.dfsHelper(board, i, j + 1, visited, word, wordIndex + 1) \
                or self.dfsHelper(board, i, j - 1, visited, word, wordIndex + 1)
        
        visited[(i, j)] = False
        return found

顺便用同一种方法肉了一圈LC 200

class Solution(object):
    def numIslands(self, grid):
        visited = {}
        res = 0
        
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == '1' and not visited.get((i, j)):
                    self.dfsHelper(grid, i, j, visited)
                    res += 1  
        return res 
    
        
    def dfsHelper(self, grid, i, j, visited):
        if i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]) or visited.get((i, j)) or grid[i][j] != '1':
            return 
        
        visited[(i, j)] = True
        self.dfsHelper(grid, i + 1, j, visited)
        self.dfsHelper(grid, i - 1, j, visited)
        self.dfsHelper(grid, i, j + 1, visited)
        self.dfsHelper(grid, i, j - 1, visited)

@tech-cow
Copy link
Owner Author

tech-cow commented Oct 13, 2019

Working Code (不使用Visited)

class Solution(object):
    def exist(self, board, word):
        for i in range(len(board)):
            for j in range(len(board[0])):
                if self.dfsHelper(board, i , j, word, 0):
                    return True
        return False
                
                
    
    def dfsHelper(self, board, i , j, word, wordIndex):
        if wordIndex == len(word):
            return True
        
        if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or word[wordIndex] != board[i][j]:
            return False
        
        board[i][j] = '#'
        
        found = self.dfsHelper(board, i + 1, j, word, wordIndex + 1) \
                or self.dfsHelper(board, i - 1, j, word, wordIndex + 1) \
                or self.dfsHelper(board, i, j + 1, word, wordIndex + 1) \
                or self.dfsHelper(board, i, j - 1, word, wordIndex + 1)
        
        board[i][j] = word[wordIndex]
        return found

@tech-cow tech-cow moved this from Coding to 彻底理解 in 刷题板 Oct 17, 2019
@tech-cow tech-cow moved this from 彻底理解 to Problem Solving in 刷题板 Jul 14, 2021
@tech-cow tech-cow moved this from Problem Solving to Coding in 刷题板 Jul 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
刷题板
  
Coding
Development

No branches or pull requests

1 participant