LeetCode130 被围绕的区域(后续)

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

不考过程序员不改名字

2022-03-29

老师,按照您的建议我重新修改了一下代码,第25个用例没通过,您能帮忙看下是逻辑上的问题还是其他细节问题嘛

public class LeetCode130 {
    boolean[][] flag;
    int[][] go = {{-1,0},{0,1},{1,0},{0,-1}};
    int m,n;
    //设置一个判断遍历元素中是否有边界元素的标志
    boolean isBoundaryFlag;
    public void solve(char[][] board) {
        m = board.length;
        if (m<1){
            return;
        }
        n = board[0].length;
        flag = new boolean[m][n];
        for (int i = 1; i < m-1; i++) {
            for (int j = 1;j<n-1;j++){
                if (!flag[i][j]&&board[i][j]=='O'){
                    dfs(board,i,j,false);
                }
            }
        }
    }
    private void dfs(char[][] board,int startX,int startY,boolean isBoundaryFlag){
        //是否为边界元素,如果是将标志位改变回溯
        if (isBoundary(startX,startY)){
            isBoundaryFlag = true;
            return;
        }
        flag[startX][startY] = true;
        board[startX][startY] = 'X';
        for (int i=0;i<4;i++){
            int newX = startX+go[i][0];
            int newY = startY+go[i][1];
            if (inArea(newX,newY)&&!flag[newX][newY]&&board[startX][startY]=='O'){
                dfs(board,newX,newY,isBoundaryFlag);
            }
            if (isBoundaryFlag){
                board[startX][startY]='O';
                break;
            }
        }
        return;
    }
    //判断是否为边界元素
    private boolean isBoundary(int x,int y){
        if (x==m-1||x==0||y==n-1||y==0){
            return true;
        }else {
            return false;
        }
    }
    //判断坐标是否在矩阵内
    private boolean inArea(int x,int y){
        if ((x>=0&&x<m)&&(y>=0&&y<n)){
            return true;
        }else {
            return false;
        }
    }
}
写回答

1回答

liuyubobobo

2022-03-30

首先,先不考虑具体的逻辑,你的代码中的 isBoundaryFlag 这个变量的设置是有问题的。


首先,你设置了两个 isBoundaryFlag,一个是类变量,一个是 dfs 中的参数。因为 dfs 中的参数和类变量的名字一样,都是 isBoundaryFlag,所以在这个函数内,这个参数覆盖了类变量 isBoundaryFlag,那么首先,类变量 isBoundaryFlag 是没有用的。


其次,如果只看 dfs 中的参数 isBoundaryFlag,你对这个参数的操作也是没有意义的。你改变了这个参数,然后直接 return 了。这个改变没有影响任何逻辑,因为 boolean 是基本数据类型,所以这个改变也不会传回上一层。


==========


如果考虑具体逻辑,先不说逻辑框架是否正确,你现在的代码是有小 bug 的。我不告诉你这个 Bug 是什么。我试了一下,你现在的代码,在 leetcode 中出错的用例是:

OOO
OOO
OOO

这是一个足够小的用例,只有 3 * 3 的 board,且答案显而易见,没有任何点应该改变。请你仔细调试你的代码,在调试过程中一步一步去看,你的代码在实际执行过程中,每一步把程序中的变量变成了什么,但是你希望的是变成什么,或者你以为的是变成什么。和你以为的是不是一样?如果不一样,自己哪里想错了。


=========


当你能把你的程序先调成能正确表达你想表达的逻辑的程度,你可能会发现你现在想的这个算法是有问题的。但是等你发现了这个问题,你想不通了,可以再来提问。


我希望你的问题是:

1)在某个用例下,你觉得你的逻辑应该得到怎样的结果,但实际却得到了怎样的结果,你想不明白了;

2)或者你明白原因出在哪里了,但是不知道怎么解决了;

3)或者出错的测试用例非常大,你很难去排查了,所以不知道该怎么做了。


如果你不去这么调试程序,你永远不能进步。对程序更深刻的理解,就在这个调试的过程,自己找到自己思维漏洞的过程中。


继续加油!:)


1
0

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

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

7408 学习 · 1150 问题

查看课程