Friday, April 12, 2013

Day 14, 36 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.
------------------------------
Only to check if all numbers in each row, column and subset are unique, this is not a Sudoku solver
Soltuion #1, check rows, columns and subsetction
notice that vector<bool> is a special container
vector declaration

class Solution {
public:
    
    // set an array of flags
    vector<int> init() {
        vector<int> flags(10);
        for (int i=0;i<9;i++) {
            flags[i] = 0;
        }
        return flags;
    }

    bool checkRowCol(vector<vector<char> > &board) {
        for (int i=0;i<9;i++) {
            vector<int> flags = init();
            vector<int> flags2 = init();
            for (int j=0;j<9;j++) {
                int m = board[i][j] - '0';
                int n = board[j][i] - '0';
                if (board[i][j] != '.') {
                    if (flags[m] == 1) {
                        return false;
                    }
                    flags[m] = 1;
                }
                if (board[j][i] != '.') {
                    if (flags2[n] == 1) {
                        return false;
                    }
                    flags2[n] = 1;
                }
            }
        }    
        return true;
    }
    
    bool checkSub (int row, int col, vector<vector<char> > &board) {
        vector<int> flags = init();
        for (int i=0;i<3;i++) {
            for (int j=0;j<3;j++) {
                char c = board[row+i][col+j];
                int tar = c - '0';
                if (c != '.') {
                    if (flags[tar] == 1) {
                        return false;
                    }
                    flags[tar] = 1;
                }
            }
        }
        return true;
    }
    
    bool checkAllSubs (vector<vector<char> > &board) {
        
        for (int i=0;i<3;i++) {
            for (int j=0;j<3;j++) {
                if (!checkSub(3*i,j*3,board)) {
                    return false;
                }
            }
        }
        return true;
    }
    
    bool isValidSudoku(vector<vector<char> > &board) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        return checkAllSubs(board) && checkRowCol(board);

    }
};
Solution #2, from others
three 2d-arrays corresponds to row, col, subset for every cell in board[][]

class Solution {
public:
    bool isValidSudoku(vector<vector<char> > &board) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<vector<bool> > rows(9, vector<bool>(9, false));
        vector<vector<bool> > cols(9, vector<bool>(9, false));
        vector<vector<bool> > blocks(9, vector<bool>(9, false));

        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (board[i][j] == '.') continue;
                int c = board[i][j] - '1'; 
                if (rows[i][c] || cols[j][c] || blocks[i - i % 3 + j / 3][c])
                    return false;
                rows[i][c] = cols[j][c] = blocks[i - i % 3 + j / 3][c] = true;
            }
        }
        return true;
    }
};

Update on Sep-04-2014
watch out for 
#1 int c = board[i][j] - '1';
#2 i - i % 3 + j / 3

In Java, updated on Feb-12th-2019
有意思的解法: https://leetcode.com/problems/valid-sudoku/discuss/15472/Short+Simple-Java-using-Strings
class Solution {
    public boolean isValidSudoku(char[][] board) {
        Set<String> set = new HashSet<>();
        
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                String c = "" + board[i][j];
                if (c.equals(".")) continue;
                String row = c + " row " + i;
                String col = c + " col " + j;
                String sub = c + " sub " + i / 3 * 3 + j / 3;
                
                if (set.contains(row) 
                    || set.contains(col)
                    || set.contains(sub)) return false;
                
                set.add(row);
                set.add(col);
                set.add(sub);
            }
        }
        
        return true;
    }
}

No comments:

Post a Comment