leetcode-36 Valid Sudoku

本文提供了一种解决数独问题的有效方法,并附带验证数独有效性的算法。通过使用行、列和子格标记来避免重复数字,确保了数独的合法性。此外,还介绍了一个通用框架,适用于多种NP问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我的简单解法:

<span style="font-family:Microsoft YaHei;font-size:14px;">class Solution {
public:
    bool isValidSudoku(vector<vector<char> > &board) {
        int rowFlag[9][9] = {0},columnFlag[9][9] = {0},subFlag[9][9] = {0};
        int i,j;
        for(i = 0; i < board.size(); i++){
            for(j = 0; j < board[i].size(); j++){
                if(board[i][j] != '.'){
                    int num = board[i][j] - '0' - 1,k = i/3*3+j/3;
                    if(rowFlag[i][num] || columnFlag[j][num] || subFlag[k][num])
                        return false;
                    rowFlag[i][num] = columnFlag[j][num] = subFlag[k][num] = 1;
                }
            }
        }
        return true;
    }
};</span>

其他参考:

这道题的方法就是用在N-Queens中介绍的常见套路。简单地说思路就是循环处理子问题,对于每个格子,带入不同的9个数,然后判合法,如果成立就递归继续,结束后把数字设回空。大家可以看出代码结构和N-Queens是完全一样的。判合法可以用Valid Sudoku做为subroutine,但是其实在这里因为每次进入时已经保证之前的board不会冲突,所以不需要判断整个盘,只需要看当前加入的数字和之前是否冲突就可以,这样可以大大提高运行效率,毕竟判合法在程序中被多次调用。实现的代码如下:

public void solveSudoku(char[][] board) {
    if(board == null || board.length != 9 || board[0].length !=9)
        return;
    helper(board,0,0);
}
private boolean helper(char[][] board, int i, int j)
{
    if(j>=9)
        return helper(board,i+1,0);
    if(i==9)
    {
        return true;
    }
    if(board[i][j]=='.')
    {
        for(int k=1;k<=9;k++)
        {
            board[i][j] = (char)(k+'0');
            if(isValid(board,i,j))
            {
                if(helper(board,i,j+1))
                    return true;
            }
            board[i][j] = '.';
        }
    }
    else
    {
        return helper(board,i,j+1);
    }
    return false;
}
private boolean isValid(char[][] board, int i, int j)
{
    for(int k=0;k<9;k++)
    {
        if(k!=j && board[i][k]==board[i][j])
            return false;
    }
    for(int k=0;k<9;k++)
    {
        if(k!=i && board[k][j]==board[i][j])
            return false;
    }        
    for(int row = i/3*3; row<i/3*3+3; row++)
    {
        for(int col=j/3*3; col<j/3*3+3; col++)
        {
            if((row!=i || col!=j) && board[row][col]==board[i][j])
                return false;
        }
    }
    return true;
}

再强调一下哈,以上方法是一个非常典型的套路,大部分NP问题的都是可以这个方法,比如N-QueensCombination SumCombinationsPermutations等。


参考:http://blog.youkuaiyun.com/linhuanmars/article/details/20748761

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值