leetcode36.有效的数独——学习笔记

题目:力扣icon-default.png?t=LBL2https://leetcode-cn.com/problems/valid-sudoku/

class Solution {
    public boolean isValidSudoku(char[][] board) {
        for(int num=0;num<9;num++){
            boolean a = checkLine(board,num);
            boolean b = checkColumn(board,num);
            if(a==false || b==false){
                return false;
            }
        }
        for(int c=0;c<9;c=c+3){
            for(int e=0;e<9;e=e+3){
                if(!checkSudoku(board,c,e)){
                    return false;
                }
            }
        }
        return true;
    }

    private boolean checkLine(char[][] board,int num){//检查行
        for(int i=0;i<9;i++){
            for(int j=i+1;j<9;j++){
                if(board[num][i]=='.' || board[num][j]=='.'){
                    continue;
                }
                if(board[num][i]==board[num][j]){
                    return false;
                }
            }
        }
        return true;
    }
    private boolean checkColumn(char[][] board,int num){//检查列
        for(int i=0;i<9;i++){
            for(int j=i+1;j<9;j++){
                if(board[i][num]=='.' || board[j][num]=='.'){
                    continue;
                }
                if(board[i][num]==board[j][num]){
                    return false;
                }
            }
        }
        return true;
    }
    private boolean checkSudoku(char[][] board,int x,int y){//x,y轴起点
        char[] copy  = new char[9];
        int co = 0;
        for(int n=0;n<3;n++){
            for(int m=0;m<3;m++){
                copy[co] = board[x+n][y+m];
                co++;
            }
        }
        for(co=0;co<9;co++){
            for(int py=co+1;py<9;py++){
                if(copy[co]==copy[py] && copy[co]!='.'){
                    return false;
                }
            }
        }
        return true;
    }
}

 

 思路:题目给出了一个9×9的数独,同个给出三个判断数独是否有效的条件。

(1)数字 1-9 在每一行只能出现一次。

(2)数字 1-9 在每一列只能出现一次。

(3)数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

我们需要根据这三条要求,来判断给定的9×9数独是否有效。这三个条件缺一不可,必须同时满足。因此我分别写出三个方法,对每行、每列和九宫格分别作出判断,其中一项不符合要求,则表示该数独无效。

1.检查行的方法。确定一个位置,然后遍历该行后的其他元素,检查在同一行中是否存在相同的元素,若存在则返回false;否则,返回true。

private boolean checkLine(char[][] board,int num){//检查行的方法
    for(int i=0;i<9;i++){
        for(int j=i+1;j<9;j++){
            if(board[num][i]=='.' || board[num][j]=='.'){
                continue;
            }
            if(board[num][i]==board[num][j]){
                return false;
            }
        }
    }
    return true;
}

2.检查列的方法。与上面的大致相同,将遍历整行改为遍历整列,同样检查在该列中是否存在相同给的元素,若存在返回false;否则,返回true。

private boolean checkColumn(char[][] board,int num){//检查列
    for(int i=0;i<9;i++){
        for(int j=i+1;j<9;j++){
            if(board[i][num]=='.' || board[j][num]=='.'){
                continue;
            }
            if(board[i][num]==board[j][num]){
                return false;
            }
        }
    }
    return true;
}

3.检查九宫格的方法。先将九宫格内的元素放入一个一维数组中,然后在一维数组中遍历,观察是否存在重复元素。若存在,则返回false;否则,返回true。(这块我感觉还能优化......即直接在二维数组中判断各个九宫格是否有重复元素,但是想得脑阔痛,而且现在快干饭了...所以就偷鸡了)

private boolean checkSudoku(char[][] board,int x,int y){//x,y轴起点
    char[] copy  = new char[9];
    int co = 0;
    for(int n=0;n<3;n++){
        for(int m=0;m<3;m++){
            copy[co] = board[x+n][y+m];
            co++;
        }
    }
    for(co=0;co<9;co++){
        for(int py=co+1;py<9;py++){
            if(copy[co]==copy[py] && copy[co]!='.'){
                return false;
            }
        }
    }
    return true;
}

 4.在主方法中调用上面写好的检查行和检查列的方法。将所有的行和所有的列都用上述的方法检查一遍,但凡一个不符合要求,直接返回false。

for(int num=0;num<9;num++){
    boolean a = checkLine(board,num);
    boolean b = checkColumn(board,num);
    if(a==false || b==false){
        return false;
    }
}

5.将一个九宫格看作一个单位,把9×9的数独分成9块(类似于一个大的九宫格)。然后将每个九宫格的起点(九宫格最左上方的元素)交给实现写好的方法checkSudoku处理,让这个方法去检查九宫格内是否存在重复的元素。只有存在一个即刻返回false。

for(int c=0;c<9;c=c+3){
    for(int e=0;e<9;e=e+3){
        if(!checkSudoku(board,c,e)){
            return false;
        }
    }
}

6.若通过上述的重重检查都没有提前返回false值,则证明该数独是有效的,在此处返回true。

return true;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hokachi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值