51、[困难] N 皇后
位运算 哈希表
class Solution {
private:
bool checkCol[10], checkDig1[20], checkDig2[20];
vector<vector<string>> ret;
vector<string> path;
int num;
void dfs(int row) {
if (row == num) {
ret.push_back(path);
return;
}
for (int col = 0; col < num; ++col) {
// 剪枝
if (!checkCol[col] && !checkDig1[row - col + num] &&
!checkDig2[row + col]) {
path[row][col] = 'Q';
checkCol[col] = checkDig1[row - col + num] = checkDig2[row + col] = true;
dfs(row + 1);
path[row][col] = '.';
checkCol[col] = checkDig1[row - col + num] = checkDig2[row + col] = false;
}
}
}
public:
vector<vector<string>> solveNQueens(int n) {
num = n;
path.resize(num);
for (int i = 0; i < num; ++i) {
path[i].append(num, '.');
}
dfs(0);
return ret;
}
};
class Solution {
private:
bool isValid(vector<pair<int, int>>& solution, int row, int col) {
// 保证和每个皇后的位置都不冲突
for (pair<int, int>& position : solution) {
// 不在同一列, 以及不在同一斜线
if (position.second == col ||
(position.first + position.second == row + col) ||
(position.first - position.second == row - col)) {
return false;
}
}
return true;
}
void dfs(vector<vector<pair<int, int>>>& solutions, vector<pair<int, int>>& solution, int row, int n) {
// 当每一行的位置都确定之后, 保存方案
if (row == n) {
solutions.push_back(solution);
return;
}
// 遍历每一列可能的位置
for (int i = 0; i < n; ++i) {
if (isValid(solution, row, i)) {
// 保存当前的皇后位置
solution.push_back(make_pair(row, i));
// 确认下一行皇后的位置
dfs(solutions, solution, row + 1, n);
// 回溯
solution.pop_back();
}
}
}
vector<vector<string>> trans(vector<vector<pair<int, int>>>& solutions, int n) {
vector<vector<string>> ret;
// 转换每一个方案
for (vector<pair<int, int>>& solution : solutions) {
vector<string> str(n, string(n, '.'));
for (pair<int, int>& pos : solution) {
// 皇后的位置赋值为 Q
str[pos.first][pos.second] = 'Q';
}
// 转换好一种方案
ret.push_back(str);
}
return ret;
}
public:
vector<vector<string>> solveNQueens(int n) {
// 所有的解决方案
vector<vector<pair<int, int>>> solutions;
// 一种解决方案
vector<pair<int, int>> solution;
dfs(solutions, solution, 0, n);
return trans(solutions, n);
}
};
52、[困难] N 皇后 Ⅱ
位运算 哈希表
class Solution {
public:
int totalNQueens(int n) {
vector<bool> checkCol(10, false), checkDig1(20, false), checkDig2(20, false);
int ret = 0;
dfs(checkCol, checkDig1, checkDig2, ret, n, 0);
return ret;
}
void dfs(vector<bool>& checkCol, vector<bool>& checkDig1, vector<bool>& checkDig2, int& ret, int n, int row) {
if (n == row) {
++ret;
return;
}
for (int col = 0; col < n; ++col) {
// 剪枝
if (!checkCol[col] && !checkDig1[row - col + n] && !checkDig2[row + col]) {
checkCol[col] = checkDig1[row - col + n] = checkDig2[row + col] = true;
dfs(checkCol, checkDig1, checkDig2, ret, n, row + 1);
checkCol[col] = checkDig1[row - col + n] = checkDig2[row + col] = false;
}
}
}
};
class Solution {
private:
bool isValid(vector<pair<int, int>>& solution, int row, int col) {
// 保证和每个皇后的位置都不冲突
for (pair<int, int>& position : solution) {
// 不在同一列, 以及不在同一斜线
if (position.second == col || (position.first + position.second == row + col) || (position.first - position.second == row - col)) {
return false;
}
}
return true;
}
void dfs(int& ret, vector<pair<int, int>>& solution, int row, int n) {
// 当每一行的位置都确定之后, 保存方案
if (row == n) {
++ret;
return;
}
// 遍历每一列可能的位置
for (int i = 0; i < n; ++i) {
if (isValid(solution, row, i)) {
// 保存当前的皇后的位置
solution.push_back(make_pair(row, i));
// 确认下一行皇后的位置
dfs(ret, solution, row + 1, n);
// 回溯
solution.pop_back();
}
}
}
public:
int totalNQueens(int n) {
int ret = 0;
vector<pair<int, int>> solution;
dfs(ret, solution, 0, n);
return ret;
}
};
53、[中等] 最大子数组和
线段树 动态规划
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n + 1);
int ret = INT_MIN;
for (int i = 1; i <= n; i++) {
dp[i] = max(nums[i - 1], dp[i - 1] + nums[i - 1]);
ret = max(ret, dp[i]);
}
return ret;
}
};
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int ret = INT_MIN, curSum = 0;
for (const auto& num : nums) {
curSum = curSum > 0 ? curSum + num : num;
ret = max(ret, curSum);
}
return ret;
}
};
54、[中等] 螺旋矩阵
数组
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> ret;
if (matrix.empty()) {
return ret;
}
int upper = 0, down = matrix.size() - 1;
int left = 0, right = matrix[0].size() - 1;
while (true) {
for (int i = left; i <= right; i++) // 向右移动直到最右
{
ret.push_back(matrix[upper][i]);
}
if (++upper >
down) // 重新设定上边界,若上边界大于下边界,则遍历遍历完成,下同
{
break;
}
for (int i = upper; i <= down; i++) // 向下
{
ret.push_back(matrix[i][right]);
}
if (--right < left) {
break;
}
for (int i = right; i >= left; i--) // 向右
{
ret.push_back(matrix[down][i]);
}
if (--down < upper) {
break;
}
for (int i = down; i >= upper; i--) // 向上
{
ret.push_back(matrix[i][left]);
}
if (++left > right) {
break;
}
}
return ret;
}
};
55、[中等] 跳跃游戏
贪心
class Solution {
public:
bool canJump(vector<int>& nums) {
int maxpos = 0;
int n = nums.size() - 1;
for (int i = 0; i <= n; ++i) {
// 判断是否可以到达当前位置
if (maxpos >= i) {
maxpos = max(maxpos, i + nums[i]);
// 判断最远的位置是否包含最后一个位置
if (maxpos >= n) {
return true;
}
} else {
return false;
}
}
return false;
}
};
56、[中等] 合并区间
排序 数组
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
int m = intervals.size();
if (m == 0) return {};
sort(intervals.begin(), intervals.end());
vector<vector<int>> ret;
for (int i = 0; i < m; i++) {
int left = intervals[i][0], right = intervals[i][1];
if (!ret.size() || ret.back()[1] < left) {
ret.push_back({left, right});
} else {
ret.back()[1] = max(ret.back()[1], right);
}
}
return ret;
}
};
57、[中等] 插入区间
数组
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals,
vector<int>& newInterval) {
int left = newInterval[0];
int right = newInterval[1];
bool placed = false;
vector<vector<int>> ret;
for (const auto& interval : intervals) {
if (interval[0] > right) {
// 在插入区间的右侧且无交集
if (!placed) {
ret.push_back({left, right});
placed = true;
}
ret.push_back(interval);
} else if (interval[1] < left) {
// 在插入区间的左侧且无交集
ret.push_back(interval);
} else {
// 与插入区间有交集,计算它们的并集
left = min(left, interval[0]);
right = max(right, interval[1]);
}
}
if (!placed) {
ret.push_back({left, right});
}
return ret;
}
};
58、[简单] 最后一个单词的长度
字符串
class Solution {
public:
int lengthOfLastWord(string s) {
int index = s.size() - 1;
while (s[index] == ' ') {
index--;
}
int wordLength = 0;
while (index >= 0 && s[index] != ' ') {
wordLength++;
index--;
}
return wordLength;
}
};
59、[中等] 螺旋矩阵 Ⅱ
数组
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> ret(n, vector<int>(n));
int left = 0, right = n - 1;
int upper = 0, down = n - 1;
int index = 1;
while (true) {
// 向右
for (int i = left; i <= right; i++) {
ret[upper][i] = index++;
}
if (++upper > down) {
break;
}
// 向下
for (int i = upper; i <= down; i++) {
ret[i][right] = index++;
}
if (--right < left) {
break;
}
// 向左
for (int i = right; i >= left; i--) {
ret[down][i] = index++;
}
if (--down < upper) {
break;
}
// 向上
for (int i = down; i >= upper; i--) {
ret[i][left] = index++;
}
if (++left > right) {
break;
}
}
return ret;
}
};