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

 

posted @ 2013-08-02 22:59  feiling  阅读(423)  评论(0编辑  收藏  举报