LeetCode 37. Sudoku Solver(DFS)

题目来源:https://leetcode.com/problems/sudoku-solver/

问题描述

37. Sudoku Solver

Hard

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

A sudoku solution must satisfy all of the following rules:

  1. Each of the digits 1-9 must occur exactly once in each row.
  2. Each of the digits 1-9 must occur exactly once in each column.
  3. Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.

Empty cells are indicated by the character '.'.

Note:

  • The given board contain only digits 1-9and the character '.'.
  • You may assume that the given Sudoku puzzle will have a single unique solution.
  • The given board size is always 9x9.

------------------------------------------------------------

题意

给定一个部分填充的数独,要求完成数独的填充。

------------------------------------------------------------

思路

解空间DFS. (好久没做搜索的题了,回溯的地方想的不是很清楚,卡了好久T_T)

具体来说,每个‘.’位置都可以放置‘1’到‘9’,总共n个‘.’位置产生9^n种可能,构成本问题的解空间。采用深度优先搜索一是因为只要找到一个可行解,二是因为方便在解空间回溯,从而可以在原数独数组上操作,不用复制原数组的备份。解空间DFS从(0, 0)位置到(8, 8)位置对所有的‘.’遍历‘1’到‘9’每一种可能,遍历时如果当前位置可行,则先向后判断直到失败回溯或全部填完找到可行解。具体实现细节请看代码。

------------------------------------------------------------

代码

class Solution {
    private boolean[][] COL, ROW, BLOCK;
    
    private void init(char[][] board)
    {
        COL = new boolean[9][9];
        ROW = new boolean[9][9];
        BLOCK = new boolean[9][9];
        int i, j, v;
        char ch = 0;
        for (i=0; i<9; i++)
        {
            for (j=0; j<9; j++)
            {
                ch = board[i][j];
                if (ch != '.')
                {
                    v = Character.getNumericValue(ch) - 1;
                    COL[j][v] = true;
                    ROW[i][v] = true;
                    BLOCK[i/3*3+j/3][v] = true;
                }
            }
        }
    }
    
    public void solveSudoku(char[][] board) {
        init(board);
        dfs(board, 0, 0);
    }
    
    private boolean dfs(char[][] board, int x, int y)
    {
        int v, xx, yy;
        if (x == 9 && y == 0)
        {
            return true;        // end of 9x9 board
        }
        if (y == 8)
        {
            xx = x + 1;
            yy = 0;
        }
        else
        {
            xx = x;
            yy = y + 1;
        }
        char ch = board[x][y];
        if (ch == '.')
        {
            for (v=0; v<9; v++)
            {
                if (!COL[y][v] && !ROW[x][v] && !BLOCK[x/3*3+y/3][v])
                {
                    board[x][y] = (char)(v + (int)'1');
                    COL[y][v] = true;
                    ROW[x][v] = true;
                    BLOCK[x/3*3+y/3][v] = true;
                    if(!dfs(board, xx, yy))
                    {
                        board[x][y] = '.';
                        COL[y][v] = false;
                        ROW[x][v] = false;
                        BLOCK[x/3*3+y/3][v] = false;
                    }
                    else
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        else
        {
            return dfs(board, xx ,yy);
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值