# 0036. Valid Sudoku ###### tags: `Leetcode` `Medium` `HashMap` Link: https://leetcode.com/problems/valid-sudoku/ ## 思路 ### 思路一 遍历一次,用27个(column9个,row9个,box9个)分别记录每行每列每个3*3的格子里面,出现每个数字的频率,如果有遇到出现两次的,直接返回false **什么时候用map,什么时候用unordered_map** https://blog.csdn.net/batuwuhanpei/article/details/50727227 ### 思路二 只用一个阵列存 每个元素都有27位 对于第```i```个元素 从右到左前9位中的第```j```位 代表第```i```行是否有```j+1```这个数字 从右到左第9~17位中的第```j```位 代表第```i```列是否有```j+1```这个数字 从右到左第18~26位中的第```j```位 代表第```i```个box是否有```j+1```这个数字 ```mux,mux1,mux2```分别存拿到```board[i][j]```之后,做bit shift,将这个值label在一个默认位0的27位int数字当中的结果,mux是在第1位到第9位里面mark,mux2是在第9位到第17位里面mark,mux3是在18~26位里面mark 之后做bit and看结果是否为0,看```board[i][j]```之前是否出现在第```i```行或第```j```列或第```((i/3)*3+(j/3))```的box里面过 ## Code ### 思路一 ```c= class Solution { public: bool isValidSudoku(vector<vector<char>>& board) { unordered_map<int,int>* rows = new unordered_map<int,int> [9]; unordered_map<int,int>* columns = new unordered_map<int,int> [9]; unordered_map<int,int>* boxes = new unordered_map<int,int> [9]; for(int i = 0;i < 9;i++){ for(int j = 0;j < 9;j++){ if(board[i][j] != '.'){ int num = board[i][j] - '0'; int box_index = (i/3)*3+j/3; if(rows[i].find(num) == rows[i].end()){ rows[i].insert(make_pair<int,int>((int)num, 1)); } else{ return false; } if(columns[j].find(num)==columns[j].end()){ columns[j].insert(make_pair<int,int>((int)num, 1)); } else{ return false; } if(boxes[box_index].find(num)==boxes[box_index].end()){ boxes[box_index].insert(make_pair<int,int>((int)num, 1)); } else{ return false; } } } } return true; } }; ``` ## Java Code ### 思路一 ```java= class Solution { public boolean isValidSudoku(char[][] board) { int[][] row = new int[9][9]; int[][] col = new int[9][9]; int[][] box = new int[9][9]; for(int i = 0;i < 9;i++){ for(int j = 0;j < 9;j++){ if(board[i][j] == '.'){ continue; } int box_index = (i/3)*3+j/3; int val = board[i][j]-'1'; if(row[i][val]==0 && col[j][val]==0 && box[box_index][val]==0){ row[i][val] = 1; col[j][val] = 1; box[box_index][val] = 1; } else{ return false; } } } return true; } } ``` ### 思路二 ```java= class Solution { public boolean isValidSudoku(char[][] board) { int[] arrayList = new int[9]; int mux, mux2, mux3, box_index; for(int i = 0;i < 9;i++){ for(int j = 0;j < 9;j++){ if(board[i][j] == '.'){ continue; } mux = 1<<board[i][j]-'1'; mux2 = 1<<(9+board[i][j]-'1'); mux3 = 1<<(9+9+board[i][j]-'1'); box_index = (i/3)*3+j/3; if((arrayList[i]&mux)==0 && (arrayList[j]&mux2)==0 && (arrayList[box_index]&mux3)==0){ arrayList[i] = arrayList[i]|mux; arrayList[j] = arrayList[j]|mux2; arrayList[box_index] = arrayList[box_index]|mux3; } else{ return false; } } } return true; } } ``` ## Result ### 思路一 in C++ Runtime: 16 ms, faster than **90.96%** of C++ online submissions for Valid Sudoku. Memory Usage: 21.3 MB, less than **11.10%** of C++ online submissions for Valid Sudoku. ### 思路一 in Java Your runtime beats **100.00 %** of java submissions. Your memory usage beats **90.89 %** of java submissions. ### 思路二 in Java Your runtime beats **100.00 %** of java submissions. Your memory usage beats **98.01 %** of java submissions. ## Error 这一题遇到的小bug特别多,要注意的写法也很多 1. character转数字 ('0'->0 '1'->1) ```int num = board[i][j] - '0';``` 2. new 的用法 创建一维阵列时(如本题) ```c= unordered_map<int,int>* rows = new unordered_map<int,int> [9]; unordered_map<int,int>* columns = new unordered_map<int,int> [9]; unordered_map<int,int>* boxes = new unordered_map<int,int> [9]; ``` 创建二维阵列时 ```c= int **matrix = new int*[ROW]; for(int i = 0; i < ROW; ++i) { matrix[i] = new int[COL]; } ``` 注意是用[],不是() 3. 在insert的部分,原本我是这样写的```rows[i].insert(make_pair<int,int>(num, 1));```,但是出现了**no matching function for call to 'make_pair'** 这个error,后来改成```rows[i].insert(make_pair<int,int>((int)num, 1));```才可以