[LeetCode][JavaScript]Valid Sudoku

Valid Sudoku

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.

The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

A partially filled sudoku which is valid.

Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.

https://leetcode.com/problems/valid-sudoku/


就是看看每行是否有重复的数字,然后看看每列,最后看小方块。

正好用了一下最近get的新姿势,没有用map存1-9是否访问过。

一个变量_bit就记下了这新信息,用位运算。

比如来的数是4,就是100,与_bit做位与,如果没有出现过100&000是0,否则100&100不等于0,最后用100|000记下4已经访问过了。

人参第一次使用四重循环,这种酸爽不敢相信。我用脚趾猜row,column,square这3种情况可以合并,但是为了纪念我人生的第一次四重循环,就这样吧(其实是懒。

不行,不重构一下我睡不着,后面有简化版。

 1 /**
 2  * @param {character[][]} board
 3  * @return {boolean}
 4  */
 5 var isValidSudoku = function(board) {
 6     this._bit = 0;
 7     function isValid(num){
 8         var tmp = Math.pow(2, num - 1);
 9         if((this._bit & tmp) !== 0){
10             return false;
11         }else{
12             this._bit = this._bit | tmp;
13             return true;
14         }
15     }
16     
17     var i = 0, j = 0, m = 0, n =0, cell = 0;
18     //row
19     for(i = 0; i < 9; i++){
20         for(j = 0; j < 9; j++){
21             cell = parseInt(board[i][j]);
22             if(!isValid(cell)){
23                 return false;
24             }
25         }
26         this._bit = 0;
27     }
28     //column
29     for(i = 0; i < 9; i++){
30         for(j = 0; j < 9; j++){
31             cell = parseInt(board[j][i]);
32             if(!isValid(cell)){
33                 return false;
34             }
35         }
36         this._bit = 0;
37     }
38     //square
39     for(i = 0; i <= 6; i+=3){
40         for(j = 0; j <=6 ; j+=3){
41             for(m = 0; m < 3; m++){
42                 for(n = 0; n < 3; n++){
43                     cell = parseInt(board[m + i][n + j]);
44                     if(!isValid(cell)){
45                         return false;
46                     }
47                 }
48             }
49             this._bit = 0;
50         }
51     }
52     return true;
53 };

合并3种情况比较麻烦啊...

前面2种好说,square的循环很纠结。

首先要用内层循环j的0-8算出下面的下标:

(0,0) (0,1) (0,2)
(1,0) (1,1) (2,2)
(2,0) (2,1) (2,2)

规律就是X = j / 3, Y = j % 3

然后要用外层循环i的0-8遍历第0个到第8个square

(0,0) (0,1) (0,2) (0,3) (0,4) (0,5)
(1,0) (1,1) (2,2) (1,3) (1,4) (2,5)
(2,0) (2,1) (2,2) (2,3) (2,4) (2,5)

(3,0) (3,1) (3,2)
(4,0) (4,1) (4,2)
(5,0) (5,1) (5,2)

画三个就能看出规律了吧,右边的square跟左上的square相比Y多了3; 下边的square跟左上的square相比X多了3; 

在内层循环的square之上加上的偏移量是:

(0,0) (0,3) (0,6)
(3,0) (3,3) (3,6)
(6,0) (6,3) (6,6)

规律就是X = (i / 3) * 3, Y = (i % 3) * 3

所以合起来就是X = (i / 3) * 3 + (j / 3) , Y = (i % 3) * 3 + (j % 3)

好费劲,心好累。

简化版在此!

js对象是引用传递,在方法里改这对象的val,相当于C指针的变通。

 1 /**
 2  * @param {character[][]} board
 3  * @return {boolean}
 4  */
 5 var isValidSudoku = function(board) {
 6     function isValid(num, flag){
 7         var tmp = Math.pow(2, num - 1);
 8         if((flag.val & tmp) !== 0){
 9             return false;
10         }else{
11             flag.val = flag.val | tmp;
12             return true;
13         }
14     }
15     
16     var i = 0, j = 0, m = 0, n =0, cell = 0;
17     var row = {val : 0}, column = {val : 0}, square = {val : 0};
18     for(i = 0; i < 9; i++){
19         for(j = 0; j < 9; j++){
20             cell = parseInt(board[i][j]);
21             if(!isValid(cell, row)){
22                 return false;
23             }
24             cell = parseInt(board[j][i]);
25             if(!isValid(cell, column)){
26                 return false;
27             }
28             cell = parseInt(board[parseInt(i / 3) * 3 + parseInt(j / 3)][(i % 3) * 3 + (j % 3)]);
29             if(!isValid(cell, square)){
30                 return false;
31             }
32         }
33         row.val = column.val = square.val = 0;
34     }
35     return true;
36 };
原文地址:https://www.cnblogs.com/Liok3187/p/4513428.html