个人记录-LeetCode 36. Valid Sudoku

问题:
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
The Sudoku board could be partially filled, where empty cells are filled with the character ‘.’.

Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.

代码示例:
1、分别检查每一行、每一列、每个独立的单元,判断是否满足有效数独问题的条件。
这个方法是最容易想到的,但需要重复扫描整个数据3次,比较费时。

public class Solution {
    public boolean isValidSudoku(char[][] board) {
     return isValid(board) && checkAllTheRow(board)
             && checkAllTheColumn(board) && checkAllUnits(board);
    }

    //检查输入数据是否正常
    private boolean isValid(char[][] board) {
        if (board == null) {
            return false;
        }

        if (board.length != 9) {
            return false;
        }

        for (int i = 0; i < 9; ++i) {
            if (board[i].length != 9) {
                return false;
            }
        }

        return true;
    }

    //检查每一行是否正常,即1~9中的数字只出现一次
    private boolean checkAllTheRow(char[][] board) {
        TreeSet<Integer> count = new TreeSet<>();

        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (board[i][j] != '.') {
                    int temp = board[i][j] - '0';
                    if (temp < 1 || temp > 9 || count.contains(temp)) {
                        return false;
                    }
                    count.add(temp);
                }
            }
            count.clear();
        }

        return true;
    }

    //检查每一列是否正常
    private boolean checkAllTheColumn(char[][] board) {
        TreeSet<Integer> count = new TreeSet<>();

        for (int j = 0; j < 9; ++j) {
            for (int i = 0; i < 9; ++i) {
                if (board[i][j] != '.') {
                    int temp = board[i][j] - '0';
                    if (temp < 1 || temp > 9 || count.contains(temp)) {
                        return false;
                    }
                    count.add(temp);
                }
            }
            count.clear();
        }

        return true;
    }

    //依次检查每一个独立的单元是否正常
    private boolean checkAllUnits(char[][] board) {
        int rowBegin = 0;
        int columnBegin = 0;
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                if (!checkUnit(board, rowBegin, columnBegin)) {
                    return false;
                }
                columnBegin += 3;
            }
            rowBegin += 3;
            columnBegin = 0;
        }

        return true;
    }

    //检查一个独立的单元
    private boolean checkUnit(char[][] board, int rowBegin, int columnBegin) {
        TreeSet<Integer> count = new TreeSet<>();

        for (int i = rowBegin; i < rowBegin + 3; ++i) {
            for (int j = columnBegin; j < columnBegin + 3; ++j) {
                if (board[i][j] != '.') {
                    int temp = board[i][j] - '0';
                    if (temp < 1 || temp > 9 || count.contains(temp)) {
                        return false;
                    }
                    count.add(temp);
                }
            }
        }

        return true;
    }
}

2、建立映射关系

public class Solution {
    public boolean isValidSudoku(char[][] board) {
        return isValid(board) && check(board);
    }

    private boolean isValid(char[][] board) {
        if (board == null) {
            return false;
        }

        if (board.length != 9) {
            return false;
        }

        for (int i = 0; i < 9; ++i) {
            if (board[i].length != 9) {
                return false;
            }
        }

        return true;
    }

    private boolean check(char[][] board) {
        //row存储每一行的信息,column存储每一列的信息,unit存储每个单元的信息
        boolean row[][] = new boolean[9][9];
        boolean column[][] = new boolean[9][9];
        boolean unit[][] = new boolean[9][9];

        for (int i = 0; i < 9; ++i) {
            for(int j = 0; j < 9; ++j) {
                if (board[i][j] == '.') {
                    continue;
                }

                int loc = board[i][j] - '1';
                //这里就是每个单元的转换关系稍微复杂一点,稍微做一下计算即可理解
                if (row[i][loc] || column[j][loc] || unit[(i/3) * 3 + j/3][loc]) {
                    return false;
                }

                row[i][loc] = true;
                column[j][loc] = true;
                unit[(i/3) * 3 + (j/3)][loc] = true;
            }
        }

        return true;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值