LeetCode(37): 每k个一组翻转链表

Hard!

题目描述:

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则:

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

空白格用 '.' 表示。

一个数独。

答案被标成红色。

Note:

  • 给定的数独序列只包含数字 1-9 和字符 '.' 。
  • 你可以假设给定的数独只有唯一解。
  • 给定数独永远是 9x9 形式的。

解题思路:

这道求解数独的题是在之前那道 Valid Sudoku 验证数独的基础上的延伸,之前那道题让我们验证给定的数组是否为数独数组,这道让我们求解数独数组。

对于每个需要填数字的格子带入1到9,每代入一个数字都判定其是否合法,如果合法就继续下一次递归。

结束时把数字设回'.',判断新加入的数字是否合法时,只需要判定当前数字是否合法,不需要判定这个数组是否为数独数组,因为之前加进的数字都是合法的,这样可以使程序更加高效一些。

C++解法一:

 1 class Solution {
 2 public:
 3     void solveSudoku(vector<vector<char> > &board) {
 4         if (board.empty() || board.size() != 9 || board[0].size() != 9) return;
 5         solveSudokuDFS(board, 0, 0);
 6     }
 7     bool solveSudokuDFS(vector<vector<char> > &board, int i, int j) {
 8         if (i == 9) return true;
 9         if (j >= 9) return solveSudokuDFS(board, i + 1, 0);
10         if (board[i][j] == '.') {
11             for (int k = 1; k <= 9; ++k) {
12                 board[i][j] = (char)(k + '0');
13                 if (isValid(board, i , j)) {
14                     if (solveSudokuDFS(board, i, j + 1)) return true;
15                 }
16                 board[i][j] = '.';
17             }
18         } else {
19             return solveSudokuDFS(board, i, j + 1);
20         }
21         return false;
22     }
23     bool isValid(vector<vector<char> > &board, int i, int j) {
24         for (int col = 0; col < 9; ++col) {
25             if (col != j && board[i][j] == board[i][col]) return false;
26         }
27         for (int row = 0; row < 9; ++row) {
28             if (row != i && board[i][j] == board[row][j]) return false;
29         }
30         for (int row = i / 3 * 3; row < i / 3 * 3 + 3; ++row) {
31             for (int col = j / 3 * 3; col < j / 3 * 3 + 3; ++col) {
32                 if ((row != i || col != j) && board[i][j] == board[row][col]) return false;
33             }
34         }
35         return true;
36     }
37 };

猜你喜欢

转载自www.cnblogs.com/ariel-dreamland/p/9138361.html