leetcode 37. Sudoku Solver 一个经典的DFS深度优先搜索的做法
2017-09-02 17:56
656 查看
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.
解决办法就是DFS深度优先搜索,这个你还需要好好学习。
这个是典型的DFS深度优先搜索,其实也是回溯的做法,这道题有一个很明显的递归套路
代码如下:
下面是C++的做法,这道题是很经典的DFS深度优先搜索遍历的做法,很值得学习
代码如下:
Empty cells are indicated by the character ‘.’.
You may assume that there will be only one unique solution.
解决办法就是DFS深度优先搜索,这个你还需要好好学习。
这个是典型的DFS深度优先搜索,其实也是回溯的做法,这道题有一个很明显的递归套路
代码如下:
public class Solution { /* * 很明显,这个是一个会回溯问题,回溯的本质就是DFS和剪枝。深度搜索常常 * 使用递归,遇到 '.'递归遍历求解,若无解,回溯 * * 一般递归函数都在开头位置判断是否结束,但是对于该问题而言,不大容易判断叶节点。 * 所以这里采用的是利用返回值true或false来对树的深度进行控制。 * 如果为solve到false时,就回溯。回溯的手段就是使用更改函数主体复位,并return。 * */ //正如上述分析,其实很简单,和N Queue很类似 public void solveSudoku(char[][] board) { solve(board); } public boolean solve(char[][] board) { //外两层循环是遍历求解 for(int i=0;i<board.length;i++) { for(int j=0;j<board[0].length;j++) { //需要解决问题的位置 if(board[i][j]=='.') { //遍历所有的可能性 for(char k='1';k<='9';k++) { //设置可能的解 board[i][j]=k; //判断是否vaild,和递归判断是否可解 if(isValid(board,i,j) && solve(board) ) return true; else //不可解的情况下,回溯,在本题就是复位即可 board[i][j]='.'; } //遍历完之后,让无答案就是无解 return false; } } } return true; } //判断当前board是否有效 boolean isValid(char[][] board,int row ,int col) { //比较行向量 for(int i=0;i<board.length;i++) if(i!=row && board[i][col]==board[row][col]) return false; //比较列向量 for(int i=0;i<board[0].length;i++) if(i!=col && board[row][i]==board[row][col]) return false; //计算小正方形的开始位置 int begRow=3*(row/3); int begCol=3*(col/3); //遍历小正方形 for(int i=begRow;i<begRow+3;i++) { for(int j=begCol;j<begCol+3;j++) { if(i!=row && j!=col && board[i][j]==board[row][col]) return false; } } return true; } }
下面是C++的做法,这道题是很经典的DFS深度优先搜索遍历的做法,很值得学习
代码如下:
#include <iostream> #include <vector> using namespace std; class Solution { public: void solveSudoku(vector<vector<char>>& board) { solveByDFS(board); } bool solveByDFS(vector<vector<char>>& board) { for (int i = 0; i < board.size(); i++) { for (int j = 0; j < board[0].size(); j++) { if (board[i][j] == '.') { for (char key = '1'; key <= '9'; key++) { board[i][j] = key; if (isVaild(board, i, j) && solveByDFS(board)) return true; else board[i][j] = '.'; } return false; } } } return true; } bool isVaild(vector<vector<char>>& board, int row, int col) { for (int i = 0; i < board[0].size(); i++) { if (i != col && board[row][i] == board[row][col]) return false; } for (int i = 0; i < board.size(); i++) { if (i != row && board[i][col] == board[row][col]) return false; } int a = 3 * (row / 3); int b = 3 * (col / 3); for (int i = a; i < a + 3; i++) { for (int j = b; j < b + 3; j++) { if (i != row && j != col && board[i][j] == board[row][col]) return false; } } return true; } };
相关文章推荐
- leetcode 139. Word Break 深度优先遍历DFS按照index递归搜索 + 很棒的动态规划DP做法
- leetcode 97. Interleaving String(字符串交错出现) DFS深度优先遍历 + 很明显很经典的DP动态规划做法
- leetcode 417. Pacific Atlantic Water Flow可以到达两边的点+经典DFS深度优先遍历做法
- leetcode 491. Increasing Subsequences所有的递增序列 + 一个典型的深度优先遍历DFS的做法
- leetcode 329. Longest Increasing Path in a Matrix 矩阵中寻找最长递增序列 + 一个典型的深度优先遍历DFS的做法
- leetcode 98. Validate Binary Search Tree DFS深度优先搜索 + 两个递归函数 + 一个错误做法
- leetcode 508. Most Frequent Subtree Sum 子树和 + 一个简单的DFS深度优先遍历的做法
- leetcode 473. Matchsticks to Square 火柴摆正方形 + 一个经典深度优先遍历DFS的应用
- leetcode 526. Beautiful Arrangement 递归实现全排列 + 经典深度优先遍历DFS做法
- leetcode 464. Can I Win 100相加游戏 + 一个十分棒的深度优先遍历DFS的做法
- leetcode 79. Word Search DFS 单词搜索 + 深度优先遍历
- leetcode 306. Additive Number 加法数的判断 + 一个典型的DFS深度优先遍地问题
- leetcode 529. Minesweeper 扫雷游戏 + 经典的DFS深度优先遍历
- Leetcode 78. Subsets Python DFS 深度优先搜索解法
- [深度优先搜索DFS]找出一组数是否能凑成一个整数
- leetcode 698. Partition to K Equal Sum Subsets K个相等子集 + 深度优先搜索DFS
- leetcode 513. Find Bottom Left Tree Value 最左边的值 + 一个简单的DFS深度优先遍历
- leetcode 140. Word Break II 深度优先搜索DFS + 很棒的动态规划DP 做法 + 记录前驱节点
- LeetCode随笔之DFS深度优先搜索
- leetcode 226. Invert Binary Tree 反转二叉树 + DFS深度优先搜索