1.Valid Sudoku
There are just 3 rules to Sudoku. | |
Each row must have the numbers 1-9 occuring just once.
| |
Each column must have the numbers 1-9 occuring just once.
| |
And the numbers 1-9 must occur just once in each of the 9 sub-boxes of the grid.
|
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.
当然这里用不到递归,下面的问题就要用到递归了。看起来比较复杂,实际比较简单,根据规则进行判断就行了。这里判重采用的map的方式
代码:
public class Solution {
//置为静态变量
static Map<Character,Integer> map = new HashMap<Character,Integer>();
public boolean isValidSudoku(char[][] board) {
//判断每行
for(int i = 0; i < board.length; i++){
initMap();//每次均需初始化
for(int j = 0; j < board[0].length; j++){
//是数字
if(board[i][j] >= '0' && board[i][j] <= '9'){
if(map.get(board[i][j]) > 0){//说明重复数字
return false;
}else{
map.put(board[i][j],1);
}
}else if(board[i][j] != '.'){//出现空格和0-9之外的字符
return false;//直接返回false
}
}
}
//判断每列
for(int i = 0; i < board[0].length; i++){
initMap();//每次均需初始化
for(int j = 0; j < board.length; j++){
//是数字
if(board[j][i] >= '0' && board[j][i] <= '9'){
if(map.get(board[j][i]) > 0){//说明重复数字
return false;
}else{
map.put(board[j][i],1);
}
}else if(board[j][i] != '.'){//出现空格和0-9之外的字符
return false;//直接返回false
}
}
}
//判断九宫格
for(int i = 0; i < board.length - 2; i = i+3){//行{
for(int j = 0; j < board[0].length - 2; j=j+3){
initMap();//初始化
for(int m = i; m < i + 3;m++){
for(int n = j; n < j+3; n++){
//是数字
if(board[m][n] >= '0' && board[m][n] <= '9'){
if(map.get(board[m][n]) > 0){//说明重复数字
return false;
}else{
map.put(board[m][n],1);
}
}else if(board[m][n] != '.'){//出现空格和0-9之外的字符
return false;//直接返回false
}
}
}
}
}
return true;
}
//初始化map为每个key均赋值0
private void initMap(){
for(char i = '0';i <= '9'; i++){
map.put(i,0);
}
}
}
2.Sudoku Solver
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:
bool dfs (vector<vector<char> > &board, int i, int j, int n ) { //函数写成return bool型,这样在找到第一个解的时候return.
if (j >= n) {
return dfs(board, i+1, 0, n);
} else if (i == n){
return true;
} else if (board[i][j] != '.'){
return dfs(board, i, j+1, n);
} else {
for (int k = 1; k <= n; ++k){
board[i][j] = (char)('0' + k);
if (isValid(board, i, j, n)){
if (dfs(board, i, j+1 , n)) // 如果找到第一个解,就及时return
return true;
}
board[i][j] = '.';
}
}
return false;
}
bool isValid(vector<vector<char>> &board, int i , int j, int n) {
for (int index = 0; index < n; ++index){
if (index != j && board[i][index] == board[i][j]) {
return false;
}
}
for (int index = 0; index < n; ++index){
if (index != i && board[index][j] == board[i][j]) {
return false;
}
}
int index_i = i / 3;
int index_j = j / 3;
for (int x = index_i * 3; x < index_i * 3 + 3; ++x) {
for (int y = index_j * 3; y < index_j * 3 + 3; ++y) {
if ((x!=i || y != j) && board[x][y] == board[i][j]) { //注意这里逻辑是"或"||,不是"与"
return false;
}
}
}
return true;
}
void solveSudoku(vector<vector<char> > &board) {
if (board.size() == 0 || board[0].size() == 0) return;
dfs(board, 0, 0, 9);
}
};
3.N-Queens
The n-queens puzzle is the problem of placing n queens on ann×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens' placement, where'Q'
and '.'
both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ]
可以有不同的方法,一种方法就是同第2题中的方法一样,每个位置进行递归,这样需要有一个棋盘,浪费了一定的空间,但是比较好理解;第二种方法,把每一行所放置的数字连起来可以看成N个数字的排列。关于生成排列的几种算法可以参考《排列组合程序》。
代码如下:
public class Solution {
public List<List<String>> solveNQueens(int n) {
ArrayList<List<String>> res = new ArrayList<List<String>>();
int[] nums = new int[n];
for(int i = 0;i<n;i++) nums[i] = i;
helper(nums,0,res);
return res;
}
public void helper(int[] nums,int pos,List<List<String>> res){
if(pos == nums.length){
save(nums,res);
return;
}
for(int i = pos;i < nums.length;i++){
swap(nums,pos,i);
if(isValidate(nums,pos))
helper(nums,pos+1,res);
swap(nums,pos,i);
}
}
public void save(int[] nums,List<List<String>> res){
ArrayList<String> tmp = new ArrayList<String>();
for(int i = 0;i < nums.length;i++){
StringBuilder sb = new StringBuilder();
for(int j = 0;j < nums.length;j++){
if(nums[i] != j) sb.append(".");
else sb.append("Q");
}
tmp.add(sb.toString());
}
res.add(tmp);
}
public void swap(int[] nums,int i,int j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public boolean isValidate(int[] nums,int pos){
for(int i = 0;i < pos;i++){
if((i+nums[i] == pos+nums[pos]) || (i-nums[i] == pos-nums[pos])) return false;
}
return true;
}
}
4.N-Queens II
Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
同上一道题一样,代码如下:
public class Solution {
private int count = 0;
public int totalNQueens(int n) {
int[] nums = new int[n];
for(int i = 0;i<n;i++) nums[i] = i;
helper(nums,0);
return count;
}
public void helper(int[] nums,int pos){
if(pos == nums.length){
count++;
return;
}else{
for(int i = pos;i < nums.length;i++){
swap(nums,pos,i);
if(isValidate(nums,pos))
helper(nums,pos+1);
swap(nums,pos,i);
}
}
}
public void swap(int[]nums,int i,int j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public boolean isValidate(int[] nums,int pos){
for(int i = 0;i < pos;i++) if((i+nums[i] == pos+nums[pos])||(i-nums[i] == pos-nums[pos])) return false;
return true;
}
}