文章目录
一、LCP 44. 开幕式焰火
1.原题链接
2.题目描述
「力扣挑战赛」开幕式开始了,空中绽放了一颗二叉树形的巨型焰火。
给定一棵二叉树 root 代表焰火,节点值表示巨型焰火这一位置的颜色种类。请帮小扣计算巨型焰火有多少种不同的颜色。
3.解题思路
深度优先搜索
4.源码
class Solution {
public:
int numColor(TreeNode* root) {
unordered_set<int> set;
stack<TreeNode*> stk;
TreeNode* cur = root;
while (cur || stk.size()) {
while (cur) {
stk.push(cur);
cur = cur->left;
}
cur = stk.top();
stk.pop();
set.insert(cur->val);
cur = cur->right;
}
return set.size();
}
};
二、102. 二叉树的层序遍历
1.原题链接
2.题目描述
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
3.解题思路
队列+广度优先搜索
4.源码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector <vector <int>> ret;
if (!root) {
return ret;
}
queue <TreeNode*> q;
q.push(root);
while (!q.empty()) {
int currentLevelSize = q.size();
ret.push_back(vector <int> ());
for (int i = 1; i <= currentLevelSize; ++i) {
auto node = q.front(); q.pop();
ret.back().push_back(node->val);
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
}
return ret;
}
};
三、1609. 奇偶树
1.原题链接
2.题目描述
如果一棵二叉树满足下述几个条件,则可以称为 奇偶树 :二叉树根节点所在层下标为 0 ,根的子节点所在层下标为 1 ,根的孙节点所在层下标为 2 ,依此类推。偶数下标 层上的所有节点的值都是 奇 整数,从左到右按顺序 严格递增奇数下标 层上的所有节点的值都是 偶 整数,从左到右按顺序 严格递减给你二叉树的根节点,如果二叉树为 奇偶树 ,则返回 true ,否则返回 false 。
3.解题思路
队列+广度优先搜索
4.源码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isEvenOddTree(TreeNode* root) {
queue<TreeNode*> qu;
qu.push(root);
int level = 0;
while (!qu.empty()) {
int size = qu.size();
int prev = level % 2 == 0 ? INT_MIN : INT_MAX;
for (int i = 0; i < size; i++) {
TreeNode * node = qu.front();
qu.pop();
int value = node->val;
if (level % 2 == value % 2) {
return false;
}
if ((level % 2 == 0 && value <= prev) || (level % 2 == 1 && value >= prev)) {
return false;
}
prev = value;
if (node->left != nullptr) {
qu.push(node->left);
}
if (node->right != nullptr) {
qu.push(node->right);
}
}
level++;
}
return true;
}
};
四、1263. 推箱子
1.原题链接
2.题目描述
「推箱子」是一款风靡全球的益智小游戏,玩家需要将箱子推到仓库中的目标位置。
3.解题思路
广度优先记忆化搜索
4.源码
class Solution {
public:
int sx, sy;// 起始人的位置
int bx, by;// 箱子的位置
int n, m;// 地图的行列
bool canM[25][25][25][25];
const int N[3] = { 15625,625,25 };
// 人 和 箱子的位置信息
int dir[4][2] = { {1,0},{0,1},{-1,0},{0,-1} };
// 判断该点是否能走到
bool get(vector<vector<char>>& g, int& x, int& y) {
if (x < 0 || y < 0 || x == n || y == m || g[x][y] == '#') {
return false;
}
return true;
}
int minPushBox(vector<vector<char>>& grid) {
n = grid.size();
m = grid[0].size();
// 获得三个标记位的位置
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 'B') bx = i, by = j;
else if (grid[i][j] == 'S') sx = i, sy = j;
}
}
// 初始化访问数组
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int k = 0; k < n; k++) memset(canM[i][j][k], false, m + 1);
}
}
// BFS 开始
canM[sx][sy][bx][by] = true;
queue<int> q;
q.push(sx * N[0] + sy * N[1] + bx * N[2] + by);
int res = 0;
while (!q.empty()) {
res++;
queue<int> nq;
while (!q.empty()) {
auto t = q.front(); q.pop();
// 人的位置
int x1 = t / N[0];
t %= N[0];
int y1 = t / N[1];
t %= N[1];
// 箱子的位置
int x2 = t / N[2];
int y2 = t % N[2];
for (int i = 0; i < 4; i++) {
// 人进行四个方向移动
int nx = x1 + dir[i][0];
int ny = y1 + dir[i][1];
if (!get(grid, nx, ny)) continue;
if (nx == x2 && ny == y2) {
int ox, oy;
ox = x2 + dir[i][0], oy = y2 + dir[i][1];
if (!get(grid, ox, oy) || canM[nx][ny][ox][oy]) continue;// 箱子不能移动的情况 或者 该情况已经搜索过
if (grid[ox][oy] == 'T') return res;// 到达目的地的情况
nq.push(nx * N[0] + ny * N[1] + ox * N[2] + oy);// 新的一个状态
canM[nx][ny][ox][oy] = true;
}
else {
if (canM[nx][ny][x2][y2]) continue;
q.push(nx * N[0] + ny * N[1] + x2 * N[2] + y2);
canM[nx][ny][x2][y2] = true;
}
}
}
while (!nq.empty()) q.push(nq.front()), nq.pop();
}
return -1;
}
};
总结
17天,推箱子还要反复思考,把完全理解。