标签:
题目:
Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character ‘.‘
.
You may assume that there will be only one unique solution.
A sudoku puzzle...
...and its solution numbers marked in red.
代码:
class Solution { public: void solveSudoku(vector<vector<char> >& board) { vector<pair<int, int> > emptyCells; vector<set<char> > rowSet, colSet, matrixSet; set<char> row, col, matrix; for ( size_t i = 0 ; i < 9; ++i ) { row.clear(); col.clear(); matrix.clear(); for ( size_t j = 0 ; j < 9; ++j ) { if (board[i][j]!=‘.‘){ row.insert(board[i][j]); } else{ emptyCells.push_back(make_pair(i, j)); } if (board[j][i]!=‘.‘) col.insert(board[j][i]); int r = j/3+(i/3)*3, c = j%3+(i%3)*3; if (board[r][c]!=‘.‘) matrix.insert(board[r][c]); } rowSet.push_back(row); colSet.push_back(col); matrixSet.push_back(matrix); } Solution::dfs(board, emptyCells, rowSet, colSet, matrixSet); } static bool dfs( vector<vector<char> >& board, vector<pair<int, int> >& emptyCell, vector<set<char> >& rowSet, vector<set<char> >& colSet, vector<set<char> >& matrixSet) { if ( emptyCell.empty() ) return true; int i = emptyCell.back().first; int j = emptyCell.back().second; for ( char v = ‘1‘; v<=‘9‘ && !emptyCell.empty(); ++v ) { if (rowSet[i].find(v)==rowSet[i].end() && colSet[j].find(v)==colSet[j].end() && matrixSet[(i/3)*3+j/3].find(v)==matrixSet[(i/3)*3+j/3].end() ) { board[i][j]=v; rowSet[i].insert(v); colSet[j].insert(v); matrixSet[(i/3)*3+j/3].insert(v); emptyCell.pop_back(); if ( Solution::dfs(board, emptyCell, rowSet, colSet, matrixSet) ) { return true; } else { emptyCell.push_back(make_pair(i, j)); board[i][j] = ‘.‘; rowSet[i].erase(v); colSet[j].erase(v); matrixSet[(i/3)*3+j/3].erase(v); } } } return false; } };
tips:
采用深搜模板。
主要思路走一遍board,得到三个set,一个vector
1. 三个set分别为每行、列、子模块已有的数字
2. 一个vector中存放着‘.‘的位置
每次处理一个‘.‘,遍历1到9:
1. 如果满足数独的条件,就往下走一层
2. 如果1到9都不满足,则退回到上一层,重新选择上一个位置的元素
这里有一个思维陷阱:
emptyCell.pop_back(); if ( Solution::dfs(board, emptyCell, rowSet, colSet, matrixSet) ) { return true; } else { emptyCell.push_back(make_pair(i, j)); board[i][j] = ‘.‘; rowSet[i].erase(v); colSet[j].erase(v); matrixSet[(i/3)*3+j/3].erase(v); }
注意:pop和push操作应该是对应的,之前一直以为可以不用push的操作,原因是忽略了一种情况:如果一个位置从1到9都不满足,那么必然要回溯到上一层;即,某一个位置的元素是可能遍历不止一次1到9的。
=================================
这里set的效率可能有些低,换一个hashmap的效率可能高一些。
标签:
原文地址:http://www.cnblogs.com/xbf9xbf/p/4537044.html