[LeetCode]SudokuSolver解决数独问题

一、 问题描述:

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.

二、解决思路:

看起来数独是个比较麻烦的问题,实际上在用程序模拟的时候是个比较简单的过程,类似于八皇后问题,可采用回溯的思想解决。

这里主要创建了三个boolean的数组分别来记录棋盘board的行、列、块的状态,并用一个linkedlist记录board中为空的格子的位置,提高扫描效率。

注意每次回溯之后恢复这些数组和容器的状态即可。


三、源码:

import java.util.*;
import java.io.*;
public class SudokuSolver {
	public void solveSudoku(char[][] board) {
        boolean[][] rowAppear = new boolean[9][9];
        boolean[][] colAppear = new boolean[9][9];
        boolean[][] blockAppear = new boolean[9][9];
        List<Integer[]> list = new LinkedList<>();
        for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++) {
				char tmp = board[i][j];
				if (tmp != '.') {
					rowAppear[i][tmp-'1']=true;
					colAppear[j][tmp-'1']=true;
					blockAppear[i/3*3+j/3][tmp-'1']=true;
				}
				else {
					list.add(new Integer[]{i,j});
				}
			}
		}
        helper(board, rowAppear, colAppear, blockAppear, list);
    }
	public boolean helper(char[][] board, boolean[][] rowAppear, boolean[][] colAppear, boolean[][] blockAppear, List<Integer[]> list) {
		if (list.isEmpty()) {
			return true;
		}
		Integer[] tmpPos = list.get(0);
		int x=tmpPos[0], y=tmpPos[1];
		list.remove(0);
		for (int i = 0; i < 9; i++) {
			if (!rowAppear[x][i] && !colAppear[y][i] && !blockAppear[x/3*3+y/3][i]) {
				board[x][y] = (char)('1'+i);
				rowAppear[x][i] = true;
				colAppear[y][i] = true;
				blockAppear[x/3*3+y/3][i] = true;
				if (helper(board, rowAppear, colAppear, blockAppear, list)) return true;
				board[x][y] = '.';
				rowAppear[x][i] = false;
				colAppear[y][i] = false;
				blockAppear[x/3*3+y/3][i] = false;
			}
		}
		list.add(0, tmpPos);
		return false;
	}
	public static void main(String[] args) {
		SudokuSolver sudokuSolver = new SudokuSolver();
		char[][] board = new char[9][9];
		Scanner scanner = new Scanner(System.in);
		for (int i = 0; i < 9; i++) {
				board[i] = scanner.next().toCharArray();
		}
		sudokuSolver.solveSudoku(board);
		for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++) {
				System.out.print(board[i][j]+" ");
			}
			System.out.print("\n");
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值