Skip to content

130 surrounded regions

130. Surrounded Regions

题目:

https://leetcode.com/problems/surrounded-regions

难度:

Medium

思路:

loop,然后碰到O做DFS/BFS找出O所在区域:

  • 貌似只要O没有碰壁,O就总是被X包围着?
  • 所以找出O的范围,然后看它是否碰壁,没有碰壁则mark不需要修改

但是这道题折磨我了很久,因为它有毛病。。。。 它给的input例子是 ["XXX","XOX","XXX"] 也怪我 input写着List[List[str]]

但实际上的输入是: [[u'X', u'X', u'X'], [u'X', u'X', u'X'], [u'X', u'X', u'X']]

还要mark unicode

还有就是学会了新的可以函数之下定义函数,这样就不用什么self了,用起来真方便,但是这样的思路做起来会超时。

class Solution(object):
    def solve(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """


        def shouldOChange(i, j):
            """
            return x,y area and whether they shouldChange
            """
            shouldChange = True
            Oarea = []
            s = []
            s.append((i,j))
            while s:
                (x,y) = s.pop()
                if x == 0 or x == row - 1 or y == 0 or y == col -1 :
                    shouldChange = False
                visited[x][y] = 1
                Oarea.append((x,y))
                if legal(x-1,y):
                    s.append((x-1,y))
                if legal(x+1,y):
                    s.append((x+1,y))
                if legal(x,y-1):
                    s.append((x,y-1))
                if legal(x,y-1):
                    s.append((x,y+1))
                return Oarea,shouldChange

        def legal(x,y):
            return x>=0 and x < row and y>=0 and y < col and board[x][y] == 'O' and visited[x][y] == 0


        row = len(board)
        col = len(board[0]) if row else 0

        visited = [[0 for i in range(col)] for j in range(row)]

        for i in range(row):
            for j in range(col):
                if board[i][j] == 'O' and visited[i][j] == 0:
                    Oarea, shouldChange = shouldOChange(i,j)
                    print Oarea,shouldChange
                    if shouldChange:
                        for (x,y) in Oarea:
                            board[x][y] = u'X'

        print board

另一个思路就是对周围碰壁的O做BFS/DFS,碰壁的和碰壁相连的是不需要修改的。这样就时间复杂度降低很多了。

原本是O(n^2)可能做DFS/BFS。现在是O(4n)做DFS/BFS,但是发现依旧超时,最后查看了别人的解法,因为我的解法里面多了一个存储工具,相当于,把需要更换location的位置存储起来,最后做loop的时候去查,然后这样还是很耗时。

而一个简便的变法是把这些特别的碰壁的'O' mark出来,这样最后loop的时候不改变这些'O',只改变不碰壁的'O',又可以减少工作量。同时依旧可以使用collection里面的queue

AC代码

class Solution(object):
    def solve(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        def legal(x,y):
            return x>=0 and x < row and y>=0 and y < col and board[x][y] == 'O' and visited[x][y] == 0


        row = len(board)
        col = len(board[0]) if row else 0

        visited = [[0 for i in range(col)] for j in range(row)]

        notChangeOArea = []
        queue = collections.deque()

        for j in range(col):
            if board[0][j] == 'O': queue.append((0,j))
            if board[row-1][j] == 'O': queue.append((row-1,j))
        for i in range(row):
            if board[i][0] == 'O': queue.append((i,0))
            if board[i][col-1] == 'O': queue.append((i,col-1))

        while queue:
            (x,y) = queue.popleft()
            board[x][y] = '$'
            visited[x][y] = 1
            if legal(x-1,y):
                queue.append((x-1,y))
            if legal(x+1,y):
                queue.append((x+1,y))
            if legal(x,y-1):
                queue.append((x,y-1))
            if legal(x,y+1):
                queue.append((x,y+1))

        for i in range(row):
            for j in range(col):
                if board[i][j] == '$' : board[i][j] = 'O'
                elif board[i][j] == 'O' : board[i][j] = 'X'

同时发现,用这种方式,无论是否使用collection里面的queue,都能AC


我们一直在努力

apachecn/AiLearning

【布客】中文翻译组