Leetcode36. Valid Sudoku

首先想到了暴力解法,O(9^2)。

 1 class Solution {
 2     public boolean isValidSudoku(char[][] board) {
 3         HashSet<Character> set = new HashSet<>();
 4         for(int i=0;i<9;i++){
 5             set.clear();
 6             for(int j=0;j<9;j++){
 7                 char element = board[i][j];
 8                 if(element=='.') continue;
 9                 if(!set.contains(element)){
10                     set.add(element);
11                 }else{
12                     return false;
13                 }
14             }
15             // if(set.isEmpty()) return false;
16         }
17         for(int i=0;i<9;i++){
18             set.clear();
19             for(int j=0;j<9;j++){
20                 char element = board[j][i];
21                                 if(element=='.') continue;
22                 if(!set.contains(element)){
23                     set.add(element);
24                 }else{
25                     return false;
26                 }
27             }
28             // if(set.isEmpty()) return false;
29         }
30         for(int i=0;i<3;i++){
31             for(int j=0;j<3;j++){
32                 set.clear();
33                 for(int k=0;k<3;k++){
34                     for(int l=0;l<3;l++){
35                         char element = board[i*3+k][j*3+l];
36                         if(element=='.') continue;
37                         if(!set.contains(element)){
38                             set.add(element);
39                         }else{
40                             return false;
41                         }
42                     }
43                 }
44                 // if(set.isEmpty()) return false;
45             }
46         }
47         return true;
48     }
49 }

19-28ms,54.73%-20.67%。

得吐槽下,要求说1-9的数没有重复,结果空行空列竟然也是valid的,于是自己给注释掉了。按照语义,空行空列不在1-9里,肯定是错的鸭 。(看了下一题发现,原来这题只是为了检查这个棋盘能不能用…那么还是对的)

然后看了大神的discuss https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings

发现的确是可以一次遍历完成的,而我遍历了三次。

可以充分利用HashSet.add方法的返回值是boolean。

class Solution {
    public boolean isValidSudoku(char[][] board) {
        HashSet<String> set = new HashSet<>();
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                char ele = board[i][j];
                if(ele!='.'){
                    if(!set.add(ele+"row"+i)||!set.add(ele+"col"+j)||!set.add(ele+"block"+i/3+'-'+j/3))
                        return false;
                }
            }
        }
        return true;
    }
}

15ms,86.48%。可以了。

有空可以研究一下11ms答案(12ms答案就不用看了,思路和我开始差不多,数据结构导致速度更快而已应该):

 1 class Solution {
 2     public boolean isValidSudoku(char[][] board) {
 3         int[] row = new int[9];
 4         int[] col = new int[9];
 5         int[] cub = new int[9];
 6         int idx = 0;
 7 
 8         for (int i = 0; i < 9; ++i) {
 9             for (int j = 0; j < 9; ++j) {
10                 if (board[i][j] != '.') {
11                     idx = 1 << (board[i][j] - '0');
12                     if ((row[i] & idx) > 0 ||
13                             (col[j] & idx) > 0 ||
14                             (cub[(i / 3) * 3 + j / 3] & idx) > 0
15                     ) {
16                         return false;
17                     }
18 
19                     row[i] |= idx;
20                     col[j] |= idx;
21                     cub[(i / 3) * 3 + j / 3] |= idx;
22                 }
23             }
24         }
25         return true;
26     }
27 }

 

posted @ 2018-12-26 21:04  大胖子球花  阅读(92)  评论(0)    收藏  举报