LeetCode130求教

来源:8-7 floodfill算法,一类经典问题 Number of Islands-

qq_山上山_0

2022-04-07

波波老司,23/58的用例没通过,但是很不理解,
输入 board = [[“X”,“O”,“X”], [“X”,“O”,“X”],[“X”,“O”,“X”]]
为什么结果是 [[‘X’, ‘O’, ‘X’], [‘X’, ‘X’, ‘X’], [‘X’, ‘O’, ‘X’]] (python3)

class Solution:

    m, n = 0, 0
    d = [[0, 1], [1, 0], [0, -1], [-1, 0]]
    used = []

    def isSide(self, x, y): #靠边的
        return x == 0 or x == self.m - 1 or y == 0 or y == self.n - 1

    def isArea(self, x, y): #棋盘内的
        return 0 <= x and x < self.m and 0 <= y and y < self.n

    def isIn(self, x, y): #距离边界为1的
        return 1 <= x and x < self.m - 1 and 1 <= y and y < self.n - 1

    def donotChangeX(self, board, startx, starty): #把与靠边的'O'都标记为已使用
        self.used[startx][starty] = True
        for i in range(4):
            newx = startx + self.d[i][0]
            newy = starty + self.d[i][1]
            if self.isArea(newx, newy) == True and self.used[newx][newy] == False and \
                    board[newx][newy] == 'O':
                self.donotChangeX(board, newx, newy)
            return

    def changeX(self, board, startx, starty): #合理范围内的 dfs
        board[startx][starty] = 'X'
        self.used[startx][starty] = True
        for i in range(4):
            newx = startx + self.d[i][0]
            newy = starty + self.d[i][1]

            if  self.used[newx][newy] == False and board[newx][newy] == 'O' and \
                    self.isIn(newx, newy) == True:
                self.changeX(board, newx, newy)
                # print(board)
        return

    def solve(self, board) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        self.m = len(board)
        if self.m > 0:
            self.n = len(board[0])

        self.used = [[False] * self.n for i in range(self.m)]

        for i in range(self.m):
            for j in range(self.n):
                if self.isSide(i, j) == True and board[i][j] == 'O' and self.used[i][j] == False:
                    self.donotChangeX(board, i, j)
                    continue
                if self.used[i][j] == False and self.isIn(i, j) == True and board[i][j] == 'O':
                    self.changeX(board, i, j)
        print(board)
写回答

1回答

liuyubobobo

2022-04-07

最大的逻辑问题是,你在一边标记和边缘相连接的区域,一边去把没有和边缘相连接的区域标记成 X。但是,当你访问一个没有和边缘相连接的中心区域的时候,和它相连接的边缘可能还没有标记(在它的右边或者下边或者左下边,根据你的逻辑还没有遍历到)。


所以,你需要先标记所有的边缘,再遍历中心区域。


代码中的一个“粗心”的地方是,donotChangeX 中的 return 缩进不正确。


==========


以下代码是我根据你的代码1做的修改,可以 AC。

class Solution:
    
    m, n = 0, 0
    d = [[0, 1], [1, 0], [0, -1], [-1, 0]]
    used = []
    
    def isSide(self, x, y): #靠边的
        return x == 0 or x == self.m - 1 or y == 0 or y == self.n - 1
    
    def isArea(self, x, y): #棋盘内的
        return 0 <= x and x < self.m and 0 <= y and y < self.n
    
    def isIn(self, x, y): #距离边界为1的
        return 1 <= x and x < self.m - 1 and 1 <= y and y < self.n - 1
    
    def donotChangeX(self, board, startx, starty): #把与靠边的'O'都标记为已使用
        self.used[startx][starty] = True
        for i in range(4):
            newx = startx + self.d[i][0]
            newy = starty + self.d[i][1]
            if self.isArea(newx, newy) == True and self.used[newx][newy] == False and \
                    board[newx][newy] == 'O':
                self.donotChangeX(board, newx, newy)
        return
    
    def changeX(self, board, startx, starty): #合理范围内的 dfs
        board[startx][starty] = 'X'
        self.used[startx][starty] = True
        for i in range(4):
            newx = startx + self.d[i][0]
            newy = starty + self.d[i][1]
            if  self.used[newx][newy] == False and board[newx][newy] == 'O' and \
                    self.isIn(newx, newy) == True:
                self.changeX(board, newx, newy)
                # print(board)
        return
    
    def solve(self, board) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        
        self.m = len(board)
        if self.m > 0:
            self.n = len(board[0])
        
        self.used = [[False] * self.n for i in range(self.m)]
        
        # 先标记边缘
        for i in range(self.m):
            if board[i][0] == 'O' and self.used[i][0] == False:
                self.donotChangeX(board, i, 0)
            if board[i][self.n - 1] == 'O' and self.used[i][self.n - 1] == False:
                self.donotChangeX(board, i, self.n - 1)
        for j in range(self.n):
            if board[0][j] == 'O' and self.used[0][j] == False:
                self.donotChangeX(board, 0, j)
            if board[self.m - 1][j] == 'O' and self.used[self.m - 1][j] == False:
                self.donotChangeX(board, self.m - 1, j)
        
        # 再遍历中心
        for i in range(1, self.m - 1):
            for j in range(1, self.n - 1):
                if self.used[i][j] == False and board[i][j] == 'O':
                    self.changeX(board, i, j)
        print(board)


继续加油!:)

2
1
qq_山上山_0
那个“粗心”伤害貌似很高啊;懂了懂了感动啊,谢谢波波老司
2022-04-07
共1条回复

玩转算法面试-- Leetcode真题分门别类讲解

课程配套大量BAT面试真题,高频算法题解析,强化训练

7408 学习 · 1150 问题

查看课程