LeetCode Algorithm 0036 - 0040
文章目录
0036 - Valid Sudoku (Medium)
Problem Link: https://leetcode.com/problems/valid-sudoku/description/
Description
Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules :
-
1. Each row must contain the digits
1-9without repetition. -
2. Each column must contain the digits
1-9without repetition. -
3. Each of the 9
3x3sub-boxes of the grid must contain the digits1-9without repetition.

A partially filled sudoku which is valid.
The Sudoku board could be partially filled, where empty cells are filled with the character '.'.
Example 1:
Input:
[
["5","3",".",".","7",".",".",".","."],
["6",".",".","1","9","5",".",".","."],
[".","9","8",".",".",".",".","6","."],
["8",".",".",".","6",".",".",".","3"],
["4",".",".","8",".","3",".",".","1"],
["7",".",".",".","2",".",".",".","6"],
[".","6",".",".",".",".","2","8","."],
[".",".",".","4","1","9",".",".","5"],
[".",".",".",".","8",".",".","7","9"]
]
Output: true
Example 2:
Input:
[
["8","3",".",".","7",".",".",".","."],
["6",".",".","1","9","5",".",".","."],
[".","9","8",".",".",".",".","6","."],
["8",".",".",".","6",".",".",".","3"],
["4",".",".","8",".","3",".",".","1"],
["7",".",".",".","2",".",".",".","6"],
[".","6",".",".",".",".","2","8","."],
[".",".",".","4","1","9",".",".","5"],
[".",".",".",".","8",".",".","7","9"]
]
Output: false
Explanation: Same as Example 1, except with the 5 in the top left corner being
modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.
Note:
-
A Sudoku board (partially filled) could be valid but is not necessarily solvable.
-
Only the filled cells need to be validated according to the mentioned rules.
-
The given board contain only digits
1-9and the character'.'. -
The given board size is always
9x9.
Solution C++
#pragma once
#include "pch.h"
// Problem: https://leetcode.com/problems/valid-sudoku/description/
namespace P36ValidSudoku
{
class Solution
{
public:
bool isValidSudoku(vector<vector<char>>& board)
{
if (board.empty())
{
return false;
}
// 这个解决方案,可以通过LeetCode,但一些数独结果是错误的。
// 例如:
//
// [[".",".",".", ".",".",".", "1",".","."]
// ,[".",".",".", ".",".",".", ".",".","."]
// ,[".",".",".", ".",".",".", ".",".","."]
//
// ,[".",".",".", ".",".",".", ".","2","."]
// ,[".",".",".", ".",".",".", ".","3","."]
// ,[".",".",".", ".",".",".", ".","4","."]
//
// ,[".",".",".", ".",".",".", ".",".","."]
// ,[".",".",".", ".",".",".", ".",".","."]
// ,[".",".",".", ".",".",".", ".",".","1"]]
//
// 本代码是true,LeetCode的官方答案运行结果也是true
// 但实际上这是一个不合格的数独,结果应该是false
// row num
bool usedRows[9][9] = { false };
// col num
bool usedCols[9][9] = { false };
// cube num
bool usedCubes[9][9] = { false };
for (int r = 0; r < board.size(); r++)
{
for (int c = 0; c < board[r].size(); c++)
{
if (board[r][c] == '.')
{
continue;
}
// 检测的数字
int checkNum = board[r][c] - '0' - 1;
// 第几个九宫格
int cubeIndex = r / 3 * 3 + c / 3;
// 数字是否已经存在
if (usedRows[r][checkNum]
|| usedCols[c][checkNum]
|| usedCubes[cubeIndex][checkNum])
{
return false;
}
usedRows[r][checkNum] = true;
usedCols[c][checkNum] = true;
usedCubes[cubeIndex][checkNum] = true;
}
}
return true;
}
};
}
0037 - Sudoku Solver (Hard)
Problem Link: https://leetcode.com/problems/sudoku-solver/description/
Description
Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules :
-
1. Each of the digits
1-9must occur exactly once in each row. -
2. Each of the digits
1-9must occur exactly once in each column. -
3. Each of the the digits
1-9must occur exactly once in each of the 93x3sub-boxes of the grid.
Empty cells are indicated by the character '.'.

A sudoku puzzle…

…and its solution numbers marked in red.
Note:
-
The given board contain only digits
1-9and the character'.'. -
You may assume that the given Sudoku puzzle will have a single unique solution.
-
The given board size is always
9x9.
Solution C++
#pragma once
#include "pch.h"
// Problem: https://leetcode.com/problems/sudoku-solver/description/
namespace P37SudokuSolver
{
class Solution
{
public:
void solveSudoku(vector<vector<char>>& board)
{
if (board.empty() || board.size() != 9 || board[0].size() != 9)
{
return;
}
// 空白处的行列坐标
vector<pair<int, int>> noNumIndexes;
// 数独是否有效
bool usedRows[9][9] = { false };
bool usedCols[9][9] = { false };
bool usedCubes[9][9] = { false };
if (!isValidSudoku(board, usedRows, usedCols, usedCubes, noNumIndexes))
{
return;
}
// 计算结果
solving(board, usedRows, usedCols, usedCubes, noNumIndexes, 0);
}
private:
// 计算数独递归
bool solving(vector<vector<char>>& board,
bool usedRows[9][9],
bool usedCols[9][9],
bool usedCubes[9][9],
vector<pair<int, int>>& noNumIndexes, // 空白处的行列坐标
int curNoNumIndex)
{
if (curNoNumIndex == noNumIndexes.size())
{
return true;
}
// 在board中的行列
pair<int, int> index = noNumIndexes[curNoNumIndex];
// 第几个九宫格
int cubeIndex = index.first / 3 * 3 + index.second / 3;
// 可以填入的数字集合
unordered_set<int> numSet = unordered_set<int>();
for (int num = 0; num < 9; num++)
{
if (usedRows[index.first][num]
|| usedCols[index.second][num]
|| usedCubes[cubeIndex][num])
{
continue;
}
numSet.insert(num);
}
// 没有可以填入的数字
if (numSet.size() == 0)
{
return false;
}
// 开始计算:挨个填入可用数字
for (int num : numSet)
{
usedRows[index.first][num] = true;
usedCols[index.second][num] = true;
usedCubes[cubeIndex][num] = true;
board[index.first][index.second] = (char)(num + 1 + '0');
if (solving(board, usedRows, usedCols, usedCubes, noNumIndexes, curNoNumIndex + 1))
{
return true;
}
// 填入的数字有错误
usedRows[index.first][num] = false;
usedCols[index.second][num] = false;
usedCubes[cubeIndex][num] = false;
}
return false;
}
// 本函数修改来自36,函数bug参考36注释
// 检测数独是否有效
bool isValidSudoku(vector<vector<char>>& board,
bool usedRows[9][9],
bool usedCols[9][9],
bool usedCubes[9][9],
vector<pair<int, int>>& noNumIndexes)
{
for (int r = 0; r < board.size(); r++)
{
for (int c = 0; c < board[r].size(); c++)
{
if (board[r][c] == '.')
{
noNumIndexes.push_back(pair<int, int>(r, c));
continue;
}
int checkNum = board[r][c] - '0' - 1;
int cubeIndex = r / 3 * 3 + c / 3;
if (usedRows[r][checkNum]
|| usedCols[c][checkNum]
|| usedCubes[cubeIndex][checkNum])
{
return false;
}
usedRows[r][checkNum] = true;
usedCols[c][checkNum] = true;
usedCubes[cubeIndex][checkNum] = true;
}
}
return true;
}
};
}
0038 - Count and Say (Easy)
Problem Link: https://leetcode.com/problems/count-and-say/description/
Description
The count-and-say sequence is the sequence of integers with the first five terms as following:
1. 1
2. 11
3. 21
4. 1211
5. 111221
1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, then one 1" or 1211.
Given an integer n where 1 ≤ n ≤ 30, generate the nth term of the count-and-say sequence.
Note: Each term of the sequence of integers will be represented as a string.
Example 1:
Input: 1
Output: "1"
Example 2:
Input: 4
Output: "1211"
Solution C++
#pragma once
#include "pch.h"
// Problem: https://leetcode.com/problems/count-and-say/description/
namespace P38CountAndSay
{
class Solution
{
public:
string countAndSay(int n)
{
// 题目意思就是,每次输出上一次出现数字的个数。
// 1. 1 1
// 2. 11 一个1
// 3. 21 两个1
// 4. 1211 一个2,一个1
// 5. 111221 一个1,一个2,2个1
// 不符合要求的数字
if (n < 1 || n > 30)
{
return "-1";
}
if (n == 1)
{
return "1";
}
string last = countAndSay(n - 1);
string cur = "";
for (size_t i = 0; i < last.size(); i++)
{
if (cur == "" || last[i] != cur.back())
{
cur += "1";
cur += last[i];
}
else
{
int index = cur.size() - 2;
cur[index] += 1;
}
}
return cur;
}
};
}
0039 - Combination Sum (Medium)
Problem Link: https://leetcode.com/problems/combination-sum/description/
Description
Given a set of candidate numbers (candidates) ( without duplicates ) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.
The same repeated number may be chosen from candidates unlimited number of times.
Note:
- All numbers (including
target) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
[7],
[2,2,3]
]
Example 2:
Input: candidates = [2,3,5], target = 8,
A solution set is:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
Solution C++
#pragma once
#include "pch.h"
// Problem: https://leetcode.com/problems/combination-sum/description/
namespace P39CombinationSum
{
class Solution
{
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target)
{
vector<vector<int>> results;
vector<int> result;
combinationSumInternal(candidates, target, results, result, 0);
return results;
}
private:
void combinationSumInternal(vector<int>& candidates,
int target,
vector<vector<int>>& results,
vector<int>& result,
int startIndex)
{
for (int i = 0; i < candidates.size(); i++)
{
int sub = target - candidates[i];
if (sub < 0)
{
continue;
}
result.push_back(candidates[i]);
if (sub == 0)
{
results.push_back(result);
}
else
{
combinationSumInternal(candidates, sub, results, result, i);
}
result.pop_back();
}
}
};
}
0040 - Combination Sum II (Medium)
Problem Link: https://leetcode.com/problems/combination-sum-ii/description/
Description
Given a set of candidate numbers (candidates) ( without duplicates ) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.
Each number in candidates may only be used once in the combination.
Note:
- All numbers (including
target) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
[1,2,2],
[5]
]
Solution C++
#pragma once
#include "pch.h"
// Problem: https://leetcode.com/problems/combination-sum-ii/description/
namespace P40CombinationSumII
{
class Solution
{
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target)
{
vector<vector<int>> results;
vector<int> result;
sort(candidates.begin(), candidates.end());
combinationSumInternal(candidates, target, results, result, 0);
return results;
}
private:
void combinationSumInternal(vector<int>& candidates,
int target,
vector<vector<int>>& results,
vector<int>& result,
int startIndex)
{
for (int i = startIndex; i < candidates.size(); i++)
{
if (i > startIndex && candidates[i] == candidates[i - 1])
{
continue;
}
int sub = target - candidates[i];
if (sub < 0)
{
continue;
}
result.push_back(candidates[i]);
if (sub == 0)
{
results.push_back(result);
}
else
{
combinationSumInternal(candidates, sub, results, result, i + 1);
}
result.pop_back();
}
}
};
}
288

被折叠的 条评论
为什么被折叠?



