37. Sudoku Solver

本文介绍了一种使用回溯法解决数独问题的程序实现。通过递归地填充空单元格,并验证每一步操作的合法性来确保解决方案的有效性。文章详细解释了算法流程并提供了具体代码示例。

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

题目

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character ‘.’.

You may assume that there will be only one unique solution.
这里写图片描述

A sudoku puzzle…

这里写图片描述
…and its solution numbers marked in red.

解析

题意:解一个数独,假设必定有一个解
思路:用回溯法(即试探法),与平常我们玩数据是一样的思路
* 每填入一个数字用check函数判断是否合理
* 试探的填入下一个数组,如果不合理返回至上一步
主循环是从第一个数字遍历至最后一个数字

需注意使用回溯法试探时,一般需要一个新的函数且该函数有返回值

代码

时间复杂度:O(n²)

class Solution {
public:
    void solveSudoku(vector<vector<char>>& board){
        solveSudoku(board,0);
    }
    bool solveSudoku(vector<vector<char>>& board,int position) {
        if(position==81)
            return true;;
        int row=position/9;
        int col=position%9;
        if(board[row][col]=='.'){
            for(int k=1;k<=9;k++){
                board[row][col]=(char)('0'+k);
                if(checkvalid(board,position))
                    if(solveSudoku(board,position+1))
                        return true;
                board[row][col]='.';
            }
        }
        else
            if(solveSudoku(board,position+1))
                return true;
        return false;
    }
    bool checkvalid(vector<vector<char>>& board,int position){
        int row=position/9;
        int col=position%9;
        int k=row/3*3+col/3;
        int target=board[row][col];
        for(int i=0;i<9;i++){
            if(i!=col&&board[row][i]==target) return false;
            if(i!=row&&board[i][col]==target) return false;
        }
        int beginx=k/3*3;
        int beginy=k%3*3;
        for(int x=beginx;x<beginx+3;x++){
            for(int y=beginy;y<beginy+3;y++){
                if(x!=row&&y!=col&&board[x][y]==target)
                    return false;
            }
        }
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值