true, 그렇지 않으면 false를 반환한다. 규칙
1. 각 행은 1~9 숫자들을 한 번만 쓸 수 있다.
2. 각 열은 1~9 숫자들을 한 번만 쓸 수 있다.
3. 3x3 크기의 내부 9개 상자들은 각각 1~9 숫자들을 한 번만 쓸 수 있다.
기존에 알고 있던 스도쿠 규칙과 동일해서 어떻게 해야 좀 더 깔끔하게 짤 수 있을지 고민했다.
단순하게 풀 수 있는 방법이지만, 굳이 스도쿠 전체를 순회하지 않아도 풀 수 있을 거 같다.
예시
idx =0일 때 (1행, 1열 검사)
1행 검사:5,3,7(row:1, col=1~9)
1열 검사:5, 6, 8, 4, 7(col=1, row:1~9)
<Integer, Boolean> Map타입의 map을 선언해서, 매 행, 열을 돌면서 저장해준다.
Map의 key 값이 이미 존재하는 경우, 스도쿠 규칙을 어겼다고 판단하고 false를 반환하면 될 것 같다.
main 함수
class Solution{
static HashMap<Character, Boolean> valid;
public boolean isValidSudoku(char[][] board) {
for(int r=0,c=0;r<board.length;r++,c++){
if(!Rowcheck(board,r)){
return false;
}
if(!Colcheck(board,c)){
return false;
}
}
// check sub-Box
for(int r=0;r<board.length;r+=3){
for(int c=0;c<board[0].length;c+=3){
if(!Boxcheck(board, r,c)) return false;
}
}
return true;
}
...
}
각 행, 열이 포함하고 있는 숫자를 저장할 Map 변수 valid를 선언한다.
먼저, 행과 열을 검사한다.
Sudoku Board 크기 만큼 행을 검사하는 RowCheck, 열을 검사하는 ColCheck 함수를 호출한다.
각 행/열이 스도쿠 규칙을 만족한다면, 내부 상자가 규칙을 지키는지 확인한다.
RowCheck / ColCheck
...
public static boolean Rowcheck(char[][] board, int row){
valid = new HashMap<>();
for(char c: board[row]){
if(c =='.') continue;
if(HandleValid(c, valid)){
return false;
}
}
return true;
}
public static boolean Colcheck(char[][] board, int col){
valid = new HashMap<>();
for(int r=0;r<board.length;r++){
if(board[r][col]=='.') continue;
if(HandleValid(board[r][col], valid))
return false;
}
}
return true;
}
...
Rowchek 함수
비어있는 cell인 경우 그냥 지나치기. 비어있지 않으면 HandleValid 함수 호출
반환값이 true인 경우 규칙을 어겼으므로 false를 반환한다.
ColCheck 함수
Row 함수와 동일하게 작동
HandleValid 함수
...
public static boolean HandleValid(char c, HashMap<Character, Boolean> valid){
if(!valid.getOrDefault(c,false)){
valid.put(c,true);
return false;
}
return true;
}
...
매개변수로 들어온 c 값이 map에 존재하는지 확인한다.
존재하지 않는 경우, valid.put(c, true) 코드가 호출하여 c를 저장하고, false를 반환한다.
이미 map에 c가 존재하는 경우 true를 반환한다.
즉, 이미 c와 동일한 값이 map에 존재하는 경우, 스도쿠 규칙을 어긴 것이다.
BoxCheck 함수
main 함수{
...
for(int r=0;r<board.length;r+=3){
for(int c=0;c<board[0].length;c+=3){
if(!Boxcheck(board, r,c)) return false;
}
}
}
public static boolean Boxcheck(char[][] board, int row, int col){
valid= new HashMap<>();
for(int r=row;r<row+3;r++){
for(int c=col;c<col+3;c++){
if(board[r][c]=='.') continue;
if(HandleValid(board[r][c],valid)){
return false;
}
}
}
return true;
}
HandleValid 함수는 RowCheck, ColCheck과 같은 방식으로 작동한다.
class Solution {
static HashMap<Character, Boolean> valid;
public static boolean HandleValid(char c, HashMap<Character, Boolean> valid){
if(!valid.getOrDefault(c,false)){
valid.put(c,true);
return false;
}
return true;
}
public static boolean Rowcheck(char[][] board, int row){
valid = new HashMap<>();
for(char c: board[row]){
if(c =='.') continue;
if(HandleValid(c, valid)){
return false;
}
}
return true;
}
public static boolean Colcheck(char[][] board, int col){
valid = new HashMap<>();
for(int r=0;r<board.length;r++){
if(board[r][col]=='.') continue;
if(HandleValid(board[r][col], valid)){
return false;
}
}
return true;
}
public static boolean Boxcheck(char[][] board, int row, int col){
valid= new HashMap<>();
for(int r=row;r<row+3;r++){
for(int c=col;c<col+3;c++){
if(board[r][c]=='.') continue;
if(HandleValid(board[r][c],valid)){
return false;
}
}
}
return true;
}
public boolean isValidSudoku(char[][] board) {
for(int r=0,c=0;r<board.length;r++,c++){
if(!Rowcheck(board,r)){
return false;
}
if(!Colcheck(board,c)){
return false;
}
}
// check sub-Box
for(int r=0;r<board.length;r+=3){
for(int c=0;c<board[0].length;c+=3){
if(!Boxcheck(board, r,c)) return false;
}
}
return true;
}
}
기능별로 함수를 분리하려고 연습하는 중이다.
HandleValid 함수의 함수명이 아숩고,, 반환값 처리 방식도 아쉽긴하다.
isNotValid 로 함수명을 변경하고 true, false 처리 방식을 변경하면 가독성이 향상될 것 같다.