Skip to content

Latest commit

 

History

History
119 lines (100 loc) · 3.74 KB

529.md

File metadata and controls

119 lines (100 loc) · 3.74 KB
  1. Minesweeper
Implement a magic directory with buildDict, and search methods.

For the method buildDict, you'll be given a list of non-repetitive words to build a dictionary.

For the method search, you'll be given a word, and judge whether if you modify exactly one character into another character in this word, the modified word is in the dictionary you just built.

Example 1:
Input: buildDict(["hello", "leetcode"]), Output: Null
Input: search("hello"), Output: False
Input: search("hhllo"), Output: True
Input: search("hell"), Output: False
Input: search("leetcoded"), Output: False
Note:
You may assume that all the inputs are consist of lowercase letters a-z.
For contest purpose, the test data is rather small by now. You could think about highly efficient algorithm after the contest.
Please remember to RESET your class variables declared in class MagicDictionary, as static/class variables are persisted across multiple test cases. Please see here for more details.

my thoughts:

1. depth first search

my solution:

**********399ms
class Solution(object):
    def updateBoard(self, board, click):
        """
        :type board: List[List[str]]
        :type click: List[int]
        :rtype: List[List[str]]
        """
        
        if board[click[0]][click[1]] == 'M':
            board[click[0]][click[1]] = 'X'
            return board
        
        n_coor = []
        
        for x in (click[0]-1, click[0], click[0]+1):
            for y in (click[1]-1, click[1], click[1]+1):
                if x>=0 and x<len(board) and y>=0 and y<len(board[0]) and (board[x][y] == 'M' or board[x][y] == 'E'):
                    if x == click[0] and y == click[1]:
                        continue
                    n_coor.append([x, y])
        
        if not n_coor:
            board[click[0]][click[1]] = 'B'
            return board
            
        neighbours = []
        for coor in n_coor:
            neighbours.append(board[coor[0]][coor[1]])
        
        foundMine = 0
        for position in neighbours:
            if position == 'M':
                foundMine += 1
                
        if foundMine != 0:
            board[click[0]][click[1]] = str(foundMine)
            return board
        else:
            board[click[0]][click[1]] = 'B'
            for coor in n_coor:
                board = self.updateBoard(board, coor)
            return board
        
        

my comments:


be more careful with the edge cases, as we are calling recursion, the click could be on a '1' or '3' which is precalculated. we want to just return the board to save some time.

from other ppl's solution:

1. remeber what has been visited, 279ms:
class Solution(object):
    def updateBoard(self, board, click):
        """
        :type board: List[List[str]]
        :type click: List[int]
        :rtype: List[List[str]]
        """
        if not board:
            return board
        m, n = len(board), len(board[0])
        frontier = [tuple(click)]
        visited = set()
        directions = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
        while frontier:
            x, y = frontier.pop(0)
            if (x, y) in visited:
                continue
            visited.add((x, y))
            if board[x][y] == 'M':
                board[x][y] = 'X'
                return board
            count = 0
            neighbors = []
            for dx, dy in directions:
                r, c = x+dx, y+dy
                if 0<=r<m and 0<=c<n:
                    neighbors.append((r, c))
                    if board[r][c] == 'M':
                        count += 1
            if count == 0:
                board[x][y] = 'B'
                frontier += neighbors
            else:
                board[x][y] = str(count)
        return board