LeetCode Sudoku Solver 数独C++程序

原创 2013年12月05日 07:47:18

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.

 

本题使用回溯法来解题,思路:

1 使用两个循环,逐个检查所有的方格

2 每到一个方格,检查到位空,以‘.'字符代表,就循环使用’1‘<=a<=9字符测试是否合法。

3 如果a合法,那么就继续填写下一个

4 如果不合法那么就回溯到上一个空格。

这里最巧妙和最难的地方就是在第2步中,逐个循环检查'1'<=a<='9'循环中使用了递归,就是如果当前字符合法,然后递归检查下个空格。这样程序就变得非常简洁。

还有难点就是判断什么时候需要返回真或者假。有两个地方:

1 当前测试'1'到'9'个数字都不合法,那么返回假

2 棋盘中所有空格都填满,那么就返回真

判断和Leetcode另外一个题目判断Sudoku是否合法的题目不同的就是,这里只需要判断当前格,一个循环就可以了,不需要判断所有的格。

	const static int SQUNUM = 9;
	const static int NUM = 3;

	bool isValid(vector<vector<char> > &board, int row, int col)
	{
		int sRow = row / NUM;
		int sCol = col / NUM;
		for (int i = 0; i < SQUNUM; i++)
		{
			if (i != col && board[row][col] == board[row][i])
				return false;
			if (i != row && board[row][col] == board[i][col])
				return false;
			int r = sRow*NUM + i/NUM, c = sCol*NUM + i%NUM;
			if (!(r == row && c == col) && board[row][col] == board[r][c])
				return false;
		}
		return true;
	}

	bool solveSudoku(vector<vector<char> > &board)
	{
		for (int i = 0; i < SQUNUM; i++)
		{
			for (int j = 0; j < SQUNUM; j++)
			{
				if (board[i][j] == '.')
				{
					//本程序精华:主要的回溯思想就是这个循环和递归体现出来
					//1. 逐个可行答案'1'->'9'去填写试一试是否可行
					for (char a = '1'; a <= '9'; a++)
					{
						//填写
						board[i][j] = a;
						//测试是否可行
						if (isValid(board, i, j) && solveSudoku(board))
							//可行返回真
							return true;
						//不可行,回溯,即回到本次回溯前的状态
						board[i][j] = '.';
					}
					//本格不符合规则,那么就可以马上返回了,所以不用到所有循环外。
					//就是不用等到之后的循环完了。
					return false;
				}
			}
		}
		//别忘记了最后,i==9&&j==9的时候跳出循环,这个时候就是成功了,要返回true
		return true;
	}


 2014-1-26 update

更新一个更加简洁容易理解, 且相对上面的程序不那么容易出错,的标准递归回溯法程序:

主要少了个两重循环,容易驾驭多了。

class Solution {
public:
    	void solveSudoku(vector<vector<char> > &board) 
	{
		solve2(board);
	}

	bool solve2(vector<vector<char> > &board, int row = 0, int col = 0)
	{
		if (row == 9) return true;

		int nr = col==8? row+1:row;
		int nc = col==8? 0:col+1;

		if (board[row][col] != '.')
		{
			if (solve2(board, nr, nc)) return true;
		}
		else
		{
			for (char i = '1'; i <= '9'; i++)
			{
				board[row][col] = i;
				if (isValid(board, row, col) && solve2(board, nr, nc)) return true;
			}
			board[row][col] = '.';
		}
		return false;
	}

	const static int SQUNUM = 9;
	const static int NUM = 3;

	bool isValid(vector<vector<char> > &board, int row, int col)
	{
		int sRow = row / NUM;
		int sCol = col / NUM;
		for (int i = 0; i < SQUNUM; i++)
		{
			if (i != col && board[row][col] == board[row][i])
				return false;
			if (i != row && board[row][col] == board[i][col])
				return false;
			//注意这里的计算公式:先定位小九宫大位置,然后小九宫里面的小位置
			int r = sRow*NUM + i/NUM, c = sCol*NUM + i%NUM;
			if (!(r == row && c == col) && board[row][col] == board[r][c])
				return false;
		}
		return true;
	}
};



 

 

 

版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/,未经本作者允许不得转载。

Sudoku Solver -- LeetCode

原题链接: http://oj.leetcode.com/problems/sudoku-solver/  这道题的方法就是用在N-Queens中介绍的常见套路。简单地说思路就是循环处理子问题,对于...
  • linhuanmars
  • linhuanmars
  • 2014年03月10日 03:56
  • 20248

Leetcode 37 Sudoku Solver

做了这道题,对backtracking的理解又加深了一点点。 1 每个backtracking的题目,最好都有独立判断isValid的程序,这样架构清楚。同时,valid判断函数在这里可以稍微研究一...
  • zxzxy1988
  • zxzxy1988
  • 2013年02月17日 21:53
  • 7726

LeetCode: Sudoku Solver

思路:(借助网上的讨论)因为题目保证只有一个
  • AIvin24
  • AIvin24
  • 2014年06月22日 18:52
  • 1862

leetcode的c++实现(一)

说在前面的话:c++的书看了几遍,但是平时写的机会比较少,所以忘得很快,俗话说读万卷书行万里路,没有实践理论的东西都是浮云。正好leetcode给我们提供了一个温故而知新的平台,我就计划借助这个平台在...
  • l_b_yuan
  • l_b_yuan
  • 2016年04月28日 19:23
  • 1321

本博客LeetCode题解索引及各类算法问题小结汇总(C++实现)

Some explains: 1),The current problems have been solved:Welcome, EbowTang! You have solved 101 / 316...
  • EbowTang
  • EbowTang
  • 2016年02月15日 17:18
  • 5516

LeetCode 3Sum 三个数和为零的集合 C++完整程序

掌握了这样的题的要诀就好办: 1 排序 2 前面的两个小数和后面的一个大数相加比较,如果小于0,那么前面的数往前进,增大; 如果大于0,那么后面的数往前进,减小。 3 前面的数和后面的数相遇,本...
  • kenden23
  • kenden23
  • 2013年11月24日 19:11
  • 4298

【LeetCode】120. Triangle 基于C++和Java的分析及解法,动态规划

120. Triangle Total Accepted: 69567 Total Submissions: 229977 Difficulty: Medium Given a triang...
  • Jin_Kwok
  • Jin_Kwok
  • 2016年05月15日 21:05
  • 1047

LeetCode OJ算法题(三十六):Sudoku Solver

题目: Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are ind...
  • op_yu
  • op_yu
  • 2014年07月25日 11:53
  • 377

关于leetcode中c++ STL 的几道题

1. Valid Parentheses 用来判断字符串中的括号是否合法的一道题。注意输入只会有 (, ) , {, }, [, ]这么几种情况。 合法的括号是以一定的顺序进行匹配的一些。比如:"()...
  • u011321908
  • u011321908
  • 2015年04月20日 10:47
  • 1051

【回溯法】Sudoku Solver

题目:leetcode Sudoku Solver   Write a program to solve a Sudoku puzzle by filling the emp...
  • bupt8846
  • bupt8846
  • 2015年04月15日 18:43
  • 370
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LeetCode Sudoku Solver 数独C++程序
举报原因:
原因补充:

(最多只允许输入30个字)