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...

 思路:回溯(Backtracking),回溯题练得太少,知道应该用回溯写,但不知如何下笔。。。。。

下面代码是参考网上博客写的,回溯题有如下几点需要注意:

1. 应当有个独立的isValid判断函数

2. 递归求解,递归函数应当有返回值来判断当前解是否正确

3. 对当前位置先取一个值,然后判断是否正确,如是,则继续下面的递归;否则,清空刚才赋的值,进行下一次尝试

 

这里isValid方法我原来是使用的Valid Sudoku的解,提交时发现会超时,参考了下别人的实现发现:有许多的判断是多余的,如:

当在[x][y]出取一个值时,只需要判断x行,y列,以及x,y所处的9宫格中是否valid即可,这样会减少很多无用的判断,代码中注释部分是

原来的实现。比较下可以提高8倍左右

 

  1 public class Solution {

  2 

  3     public static void main(String[] args) {

  4         // TODO Auto-generated method stub

  5         char[][] board = new char[][] { "..9748...".toCharArray(),

  6                 "7........".toCharArray(), ".2.1.9...".toCharArray(),

  7                 "..7...24.".toCharArray(), ".64.1.59.".toCharArray(),

  8                 ".98...3..".toCharArray(), "...8.3.2.".toCharArray(),

  9                 "........6".toCharArray(), "...2759..".toCharArray() };

 10         long start = System.nanoTime();

 11         solveSudokuRecursive(board);

 12         long end = System.nanoTime();

 13         System.out.println((end - start) * 1e-6);

 14         for (int i = 0; i < 9; i++) {

 15             for (int j = 0; j < 9; j++) {

 16                 System.out.print(board[i][j]);

 17                 System.out.print(' ');

 18             }

 19             System.out.println();

 20         }

 21 

 22     }

 23 

 24     public void solveSudoku(char[][] board) {

 25         // Start typing your Java solution below

 26         // DO NOT write main() function

 27         solveSudokuRecursive(board);

 28     }

 29 

 30     public static boolean solveSudokuRecursive(char[][] board) {

 31         int[] pairs = getFirstEmpty(board);

 32         if (pairs[0] == -1 && pairs[1] == -1)

 33             return true;

 34         for (int i = 1; i <= 9; i++) {

 35             board[pairs[0]][pairs[1]] = (char) (i + '0');

 36             if (isValid(board, pairs[0], pairs[1])

 37                     && solveSudokuRecursive(board)) {

 38                 return true;

 39             }

 40             // backtrack

 41             board[pairs[0]][pairs[1]] = '.';

 42         }

 43         return false;

 44     }

 45 

 46     public static int[] getFirstEmpty(char[][] board) {

 47         int[] pairs = null;

 48         for (int i = 0; i < 9; i++) {

 49             for (int j = 0; j < 9; j++) {

 50                 if (board[i][j] == '.') {

 51                     pairs = new int[] { i, j };

 52                     return pairs;

 53                 }

 54             }

 55         }

 56         pairs = new int[] { -1, -1 };

 57         return pairs;

 58     }

 59 

 60     /**

 61      * reduce some unnecessary compare by transport two parameters

 62      * 

 63      * @param board

 64      * @param x

 65      * @param y

 66      * @return

 67      */

 68     public static boolean isValid(char[][] board, int x, int y) {

 69         // Set<Character> row = new HashSet<Character>();

 70         // Set<Character> col = new HashSet<Character>();

 71 

 72         for (int i = 0; i < 9; i++) {

 73             if (i != y && board[x][i] == board[x][y])

 74                 return false;

 75 

 76             if (i != x && board[i][y] == board[x][y])

 77                 return false;

 78         }

 79 

 80 //        for (int i = 0; i < 9; i++) {

 81 //            row.clear();

 82 //            col.clear();

 83 //            for (int j = 0; j < 9; j++) {

 84 //                if (board[i][j] != '.') {

 85 //                    if (row.contains(board[i][j]))

 86 //                        return false;

 87 //                    else {

 88 //                        row.add(board[i][j]);

 89 //                    }

 90 //                }

 91 //

 92 //                if (board[j][i] != '.') {

 93 //                    if (col.contains(board[j][i]))

 94 //                        return false;

 95 //                    else

 96 //                        col.add(board[j][i]);

 97 //                }

 98 //

 99 //            }

100 //        }

101         int xIdx = (x / 3) * 3;

102         int yIdx = (y / 3) * 3;

103         for (int m = 0; m < 3; m++) {

104             for (int n = 0; n < 3; n++) {

105                 if(m + xIdx != x && n + yIdx != y && board[m + xIdx][n + yIdx] == board[x][y])// 判断9宫格中是否存在board[x][y]

106                     return false;

107             }

108         }

109 

110 //        Set<Character> container = new HashSet<Character>();

111 //        for (int i = 0; i < 9; i += 3) {

112 //            for (int j = 0; j < 9; j += 3) {

113 //                for (int m = 0; m < 3; m++) {

114 //                    for (int n = 0; n < 3; n++) {

115 //                        if (board[m + i][n + j] == '.') {

116 //                            continue;

117 //                        }

118 //                        if (container.contains(board[m + i][n + j]))

119 //                            return false;

120 //                        else {

121 //                            container.add(board[m + i][n + j]);

122 //                        }

123 //                    }

124 //

125 //                }

126 //                container.clear();

127 //            }

128 //        }

129         return true;

130     }

131 }

 ref:http://blog.csdn.net/zxzxy1988/article/details/8586289

 

你可能感兴趣的:(LeetCode)