leetcode 37 Sudoku Solver java

求数独,只要求做出一个答案就可以。

刚开始对题意理解错误,以为答案是唯一的, 所以做了很久并没有做出来,发现答案不唯一之后,使用回溯。(还是借鉴了一下别人)

public class Solution {
    public void solveSudoku(char[][] board) {
        HashSet[] hashset = new HashSet[27];
		for (int i = 0; i < 27; i++)
			hashset[i] = new HashSet<Character>();
		for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++) {
				char Char = board[i][j];
				if (Char != ‘.‘) {
						hashset[i].add(Char);
						hashset[9 + j].add(Char);
						hashset[18 + (i / 3) * 3 + j / 3].add(Char);
				}
			}
		}
		int flag = 0;
		char[][][] num = null ;
		while ( flag == 0) {
			flag = 1;
			num = new char[9][9][9];
			for (int i = 0; i < 9; i++) {// i代表第i个hashset
				for (int j = 1; j < 10; j++) {// j代表1-9
					char ch = (char) (j + ‘0‘);
					int[] test = new int[2];
					if (!hashset[i].contains(ch)) {
						test[0] = 0;
						for (int k = 0; k < 9; k++) {
							char Ch = board[i][k];
							if (Ch == ‘.‘) {
								if (!hashset[9 + k].contains(ch) && !hashset[18 + (i / 3) * 3 + k / 3].contains(ch)) {
									addNum(num, i, k, ch);
									test[0]++;
									test[1] = k;
								}
							}
						}
					}
					if (test[0] == 1) {
						board[i][test[1]] = ch;
						hashset[i].add(ch);
						flag = 0;
						hashset[9 + test[1]].add(ch);
						hashset[18 + (i / 3) * 3 + test[1] / 3].add(ch);
					}

				}
			}

			for (int qq = 0; qq < 9 && flag == 1; qq++) {
				for (int j = 0; j < 9 && flag == 1; j++) {
					if (getlen(num[qq][j]) == 1) {
						char ch = num[qq][j][0];
						board[qq][j] = ch;
						flag = 0;
						hashset[qq].add(ch);
						hashset[9 + j].add(ch);
						hashset[18 + (qq / 3) * 3 + j / 3].add(ch);
					}

				}
			}

		}
        solve(board);
    }

    public boolean solve(char[][] board){
        for(int i = 0; i < board.length; i++){
            for(int j = 0; j < board[0].length; j++){
                if(board[i][j] == ‘.‘){
                    for(char c = ‘1‘; c <= ‘9‘; c++){//trial. Try 1 through 9 for each cell
                        if(isValid(board, i, j, c)){
                            board[i][j] = c; //Put c for this cell

                            if(solve(board))
                                return true; //If it‘s the solution return true
                            else
                                board[i][j] = ‘.‘; //Otherwise go back
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }

    public boolean isValid(char[][] board, int i, int j, char c){
        for(int row = 0; row < 9; row++)
            if(board[row][j] == c)
                return false;

        for(int col = 0; col < 9; col++)
            if(board[i][col] == c)
                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(board[row][col] == c)
                    return false;
        return true;
    }
    public static int getlen(char[] num) {
		int len = 0;
		for (int i = 0; i < 9; i++) {
			if (num[i] < ‘1‘ || num[i] > ‘9‘) {
				return len;
			} else
				len++;
		}
		return len;
	}

	public static void addNum(char[][][] num, int num1, int num2, char ch) {
		for (int i = 0; i < 9; i++) {
			if (num[num1][num2][i] < ‘0‘ || num[num1][num2][i] > ‘9‘) {
				num[num1][num2][i] = ch;
				break;
			}

		}

	}
}

回溯法还是比较简单的,就是在实现的时候,如果想要提高运行的速度和空间,那么需要费一些心思来考虑。

附上借鉴的代码

public class Solution {
    public void solveSudoku(char[][] board) {
        if(board == null || board.length == 0)
            return;
        solve(board);
    }

    public boolean solve(char[][] board){
        for(int i = 0; i < board.length; i++){
            for(int j = 0; j < board[0].length; j++){
                if(board[i][j] == ‘.‘){
                    for(char c = ‘1‘; c <= ‘9‘; c++){//trial. Try 1 through 9 for each cell
                        if(isValid(board, i, j, c)){
                            board[i][j] = c; //Put c for this cell

                            if(solve(board))
                                return true; //If it‘s the solution return true
                            else
                                board[i][j] = ‘.‘; //Otherwise go back
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }

    public boolean isValid(char[][] board, int i, int j, char c){
        //Check colum
        for(int row = 0; row < 9; row++)
            if(board[row][j] == c)
                return false;

        //Check row
        for(int col = 0; col < 9; col++)
            if(board[i][col] == c)
                return false;

        //Check 3 x 3 block
        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(board[row][col] == c)
                    return false;
        return true;
    }
}
时间: 2024-10-29 03:47:30

leetcode 37 Sudoku Solver java的相关文章

LeetCode 37 Sudoku Solver (C,C++,Java,Python)

Problem: 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. So

Java [leetcode 37]Sudoku Solver

题目描述: 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. 解题思路:

[LeetCode] 37. Sudoku Solver 求解数独

Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy all of the following rules: Each of the digits 1-9 must occur exactly once in each row. Each of the digits 1-9 must occur exactly once in each column.

LeetCode 37 Sudoku Solver(求解数独)

题目链接: https://leetcode.com/problems/sudoku-solver/?tab=Description Problem : 解决数独问题,给出一个二维数组,将这个数独进行求解. 思路: 嵌套循环,三层循环体,每一行,每一列,填入从1到9的数字.判断填入之后是否合理 判断数独是否合理的函数 参考代码: package leetcode_50; /*** * * @author pengfei_zheng * 求解数独问题 */ public class Solutio

[leetcode 37]sudoku solver

1 题目: 根据给出的数独,全部填出来 2 思路: 为了做出来,我自己人工做了一遍题目给的数独.思路是看要填的数字横.竖.子是否已经有1-9的数字,有就剔除一个,最后剩下一个的话,就填上.一遍一遍的循环,直到填完为止. 后来发现,这个思路只能解决部分数独.还有部分数独是需要回溯的,比如,这个位置只能填3或5,那么就需要先填上3,看看能否继续填下去,不能的话,再回过来填5. 想了半天,想不出来,把别人的backtracking看懂了,写出来了.. 3 代码: 自己的: Hashtable<Inte

【leetcode】 Sudoku Solver

问题: 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. 说明: 数独有

37. Sudoku Solver(js)

37. Sudoku Solver Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy all of the following rules: Each of the digits 1-9 must occur exactly once in each row. Each of the digits 1-9 must occur exactly on

[Leetcode][Python]37: Sudoku Solver

# -*- coding: utf8 -*-'''__author__ = '[email protected]' 37: Sudoku Solverhttps://oj.leetcode.com/problems/sudoku-solver/ Write a program to solve a Sudoku puzzle by filling the empty cells.Empty cells are indicated by the character '.'.You may assu

[LeetCode][JavaScript]Sudoku Solver

Sudoku Solver 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 re