104. 二叉树的最大深度
https://leetcode.cn/problems/maximum-depth-of-binary-tree/
思路:可以用递归的思路,从上往下执行。对于每个节点,若左右子节点都为空,则该节点为根的子树最大深度为1。若左右子节点不为空,则该节点为根的子树最大深度为左右子节点为子树最大深度较大的再加1。
代码:
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == NULL) return 0 ;
int res = 1 ;
if (root->left != NULL) {
int r = maxDepth(root->left) ;
if (r + 1 > res) res = r + 1 ;
}
if (root->right != NULL) {
int r = maxDepth(root->right) ;
if (r + 1 > res) res = r + 1 ;
}
// cout << root->val << " " << res << endl ;
return res ;
}
};
101. 对称二叉树
https://leetcode.cn/problems/symmetric-tree/
思路:如果二叉树是对称的,那么先序遍历喝后续遍历应该是一样的。过程中间,对空节点用-1来代替,防止部分情况下不同的两棵树,先序遍历却相同的情况。
vector<int> rr ;
vector<int> ll ;
void dfsl(TreeNode* root) {
if (root == NULL) {
ll.push_back(-1) ;
return ;
}
dfsl(root->left) ;
dfsl(root->right) ;
ll.push_back(root->val) ;
}
void dfsr(TreeNode* root) {
if (root == NULL) {
rr.push_back(-1) ;
return ;
}
dfsr(root->right) ;
dfsr(root->left) ;
rr.push_back(root->val) ;
}
class Solution {
public:
bool isSymmetric(TreeNode* root) {
rr.clear() ;
ll.clear() ;
dfsl(root) ;
dfsr(root) ;
for (int i = 0 ; i < ll.size() ; ++i) {
cout << ll[i] << " " << rr[i] << endl ;
if (ll[i] != rr[i]) {
return false ;
}
}
return true ;
}
};
111. 二叉树的最小深度
https://leetcode.cn/problems/minimum-depth-of-binary-tree/
思路:可以用递归的思路,从上往下执行。对于每个节点,若左右子节点都为空,则该节点为根的子树最小深度为1。若左右子节点不为空,则该节点为根的子树最小深度为左右子节点为子树最小深度较小的再加1。
代码:
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == NULL) return 0 ;
if (root->left == NULL && root->right == NULL) {
return 1 ;
}
int res = 1e5 ;
if (root->left != NULL) {
res = min(minDepth(root->left) + 1 , res) ;
}
if (root->right != NULL) {
res = min(minDepth(root->right) + 1 , res) ;
}
return res ;
}
};
733. 图像渲染
https://leetcode.cn/problems/flood-fill/
思路:
记录初始点的值,从初始点向四周搜索,若搜到的点颜色与初始点的值相同,进行染色。
代码:
int vis[100][100] ;
class Solution {
public:
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
memset(vis , 0 , sizeof(vis)) ;
queue<int>x, y ;
x.push(sr) ;
y.push(sc) ;
int dirx[] = {0 , 1 , 0 , -1} ;
int diry[] = {1 , 0 , -1 , 0} ;
int oldcolor = image[sr][sc] ;
vis[sr][sc] = 1 ;
while (!x.empty()) {
int nowx = x.front() ;
x.pop() ;
int nowy = y.front() ;
y.pop() ;
image[nowx][nowy] = color ;
for (int i = 0 ; i < 4 ; ++i) {
int nx = nowx + dirx[i] ;
int ny = nowy + diry[i] ;
if (nx < 0) continue ;
if (ny < 0) continue ;
if (nx >= image.size()) continue ;
if (ny >= image[0].size()) continue ;
if (vis[nx][ny] == 1) continue ;
vis[nx][ny] = 1 ;
if (image[nx][ny] == oldcolor) {
x.push(nx) ;
y.push(ny) ;
}
}
}
return image ;
}
};
690. 员工的重要性
https://leetcode.cn/problems/employee-importance/description/
思路:象遍历树一样,从头节点往下搜,然后逐个累加重要度。
代码:
int id2index[2005] ;
class Solution {
public:
int getImportance(vector<Employee*> employees, int id) {
for (int i = 0 ; i < employees.size() ; ++i) {
id2index[employees[i]->id] = i ;
}
queue<int> Q ;
Q.push(id) ;
int res = 0 ;
while (!Q.empty()) {
int now = Q.front() ;
Q.pop() ;
int index = id2index[now] ;
res += employees[index]->importance ;
for (int i = 0 ; i < employees[index]->subordinates.size() ; ++i) {
Q.push(employees[index]->subordinates[i]) ;
}
}
return res ;
}
};
841. 钥匙和房间
https://leetcode.cn/problems/keys-and-rooms/
思路:按照搜索思路,逐个打开可以打开的房间,过程中统计打开了多少房间,与总房间数比对
代码:
int vis[1005] ;
class Solution {
public:
bool canVisitAllRooms(vector<vector<int>>& rooms) {
memset(vis , 0 , sizeof(vis)) ;
queue<int>Q ;
Q.push(0) ;
int cnt = 1 ;
vis[0] = 1 ;
while (!Q.empty()) {
int now = Q.front() ;
Q.pop() ;
for (int i = 0 ; i < rooms[now].size() ; ++i) {
int nx = rooms[now][i] ;
if (vis[nx] == 0) {
Q.push(nx) ;
++cnt ;
}
vis[nx] = 1 ;
}
}
if (cnt == rooms.size()) {
return true ;
}
return false ;
}
};
130. 被围绕的区域
https://leetcode.cn/problems/surrounded-regions/
思路:暴力,因为地图比较小,100步就可以往里渗透
代码:
int vis[205][205] ;
class Solution {
public:
void solve(vector<vector<char>>& board) {
memset(vis , 0 , sizeof(vis)) ;
int n = board.size() ;
int m = board[0].size() ;
for (int time = 0 ; time < 100 + 5 ; ++time) {
for (int i = 0 ; i < n ; ++i) {
for (int j = 0 ; j < m ; ++j) {
if (board[i][j] == 'X') continue ;
if (i == 0 || j == 0 || i == n - 1 || j == m - 1) {
vis[i][j] = 1 ;
continue ;
}
if (vis[i - 1][j]) vis[i][j] = 1 ;
if (vis[i + 1][j]) vis[i][j] = 1 ;
if (vis[i][j + 1]) vis[i][j] = 1 ;
if (vis[i][j - 1]) vis[i][j] = 1 ;
}
}
}
for (int i = 0 ; i < n ; ++i) {
for (int j = 0 ; j < m ; ++j) {
if (!vis[i][j]) {
if(board[i][j] == 'O') {
board[i][j] = 'X' ;
}
}
}
}
return ;
}
};
113. 路径总和 II
https://leetcode.cn/problems/path-sum-ii/
思路:DFS搜索,到每个叶子节点判断是否符合题目要求。
代码:
vector<int>V ;
vector<vector<int>> res ;
int sum = 0 ;
int aim = 0 ;
void DFS(TreeNode* now) {
if (now == NULL) return ;
sum += now->val ;
V.push_back(now->val) ;
if (now->left != NULL) {
DFS(now->left) ;
}
if (now->right != NULL) {
DFS(now->right) ;
}
if (now->right == NULL && now->left == NULL) {
if (sum == aim) {
res.push_back(V) ;
}
}
sum -= now->val ;
V.pop_back() ;
}
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
aim = targetSum ;
V.clear() ;
res.clear() ;
DFS(root) ;
return res ;
}
};
542. 01 矩阵
https://leetcode.cn/problems/01-matrix/
思路:有点BFS的思路,从0点逐步向外搜索。
代码:
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
map<pair<int,int>,int> M ;
cout << M[make_pair(1 , 1)] << endl ;
int n = mat.size() ;
int m = mat[0].size() ;
queue<pair<int,int>> Q ;
for (int i = 0 ; i < n ; ++i) {
for (int j = 0 ; j < m ; ++j) {
if (mat[i][j] == 0) {
Q.push(make_pair(i , j)) ;
M[make_pair(i , j)] = 1 ;
}
}
}
int dirx[] = {0 , 1 , 0 , -1} ;
int diry[] = {1 , 0 , -1 , 0} ;
while(!Q.empty()) {
int nowx = Q.front().first ;
int nowy = Q.front().second ;
Q.pop() ;
for (int i = 0 ; i < 4 ; ++i) {
int nexx = nowx + dirx[i] ;
int nexy = nowy + diry[i] ;
if (nexx < 0 || nexy < 0 || nexx == n || nexy == m) {
continue ;
}
if (M[make_pair(nexx , nexy)] == 1) continue ;
mat[nexx][nexy] = mat[nowx][nowy] + 1 ;
Q.push(make_pair(nexx , nexy)) ;
M[make_pair(nexx , nexy)] = 1 ;
}
}
return mat ;
}
};
417. 太平洋大西洋水流问题
https://leetcode.cn/problems/pacific-atlantic-water-flow/
思路:搞两次BFS,一次用来统计能到左上角的方块,一次用来统计能到右下角的方块。
代码:
struct Node {
int x ;
int y ;
};
class Solution {
public:
vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
int n = heights.size() ;
int m = heights[0].size() ;
int dirx[] = {0 , 1 , 0 , -1} ;
int diry[] = {1 , 0 , -1 , 0} ;
vector<vector<int>> vis ;
vis = vector(n , vector(m , 0)) ;
vector<vector<int>> res1(n , vector(m , 0)) ;
vector<vector<int>> res2(n , vector(m , 0)) ;
queue<Node> Q ;
Node now ;
for (int i = 0 ; i < n ; ++i) {
now.x = i ;
now.y = 0 ;
Q.push(now) ;
res1[i][0] = 1 ;
}
for (int i = 0 ; i < m ; ++i) {
now.x = 0 ;
now.y = i ;
Q.push(now) ;
res1[0][i] = 1 ;
}
while (!Q.empty()) {
now = Q.front() ;
Q.pop() ;
int nowx = now.x ;
int nowy = now.y ;
for (int i = 0 ; i < 4 ; ++i) {
int newx = nowx + dirx[i] ;
int newy = nowy + diry[i] ;
if (newx < 0 || newy < 0 || newx == n || newy == m) continue ;
if (vis[newx][newy]) continue ;
if (heights[newx][newy] >= heights[nowx][nowy]) {
now.x = newx ;
now.y = newy ;
Q.push(now) ;
vis[newx][newy] = 1;
res1[newx][newy] = 1 ;
}
}
}
vis = vector(n , vector(m , 0)) ;
for (int i = 0 ; i < n ; ++i) {
now.x = i ;
now.y = m - 1 ;
Q.push(now) ;
res2[i][m - 1] = 1 ;
}
for (int i = 0 ; i < m ; ++i) {
now.x = n - 1 ;
now.y = i ;
Q.push(now) ;
res2[n - 1][i] = 1 ;
}
while (!Q.empty()) {
now = Q.front() ;
Q.pop() ;
int nowx = now.x ;
int nowy = now.y ;
for (int i = 0 ; i < 4 ; ++i) {
int newx = nowx + dirx[i] ;
int newy = nowy + diry[i] ;
if (newx < 0 || newy < 0 || newx == n || newy == m) continue ;
if (vis[newx][newy]) continue ;
if (heights[newx][newy] >= heights[nowx][nowy]) {
now.x = newx ;
now.y = newy ;
Q.push(now) ;
vis[newx][newy] = 1;
res2[newx][newy] = 1 ;
}
}
}
vector<vector<int>> res ;
vector<int> res_tmp ;
res_tmp.push_back(0) ;
res_tmp.push_back(0) ;
for (int i = 0 ; i < n ; ++i) {
for (int j = 0 ; j < m ; ++j) {
if (res1[i][j] && res2[i][j]) {
res_tmp[0] = i ;
res_tmp[1] = j ;
res.push_back(res_tmp) ;
}
}
}
return res ;
}
};
473. 火柴拼正方形
https://leetcode.cn/problems/matchsticks-to-square/
思路:好像只能去搜索。相当于四个桶往里面放东西。然后从大的优先开始放。因为只有15个火柴,所以搜索量不会特别大。
代码:
int sum[4] ;
bool solve(vector<int>& matchsticks , int id , int u) {
if (id == matchsticks.size()) {
return true ;
}
for (int i = 0 ; i < 4 ; ++i) {
if (sum[i] + matchsticks[id] > u) {
continue ;
}
else {
sum[i] += matchsticks[id] ;
if (solve(matchsticks , id + 1 , u)) {
return true ;
}
sum[i] -= matchsticks[id] ;
}
}
return false ;
}
int cmp (int a , int b) {
return a > b ;
}
class Solution {
public:
bool makesquare(vector<int>& matchsticks) {
int s = 0 ;
for (int i = 0 ; i < 4 ; ++i) {
sum[i] = 0 ;
}
for (int i = 0 ; i < matchsticks.size() ; ++i) {
s += matchsticks[i] ;
}
if (s % 4 != 0) return false ;
cout << "yes!" << endl ;
sort(matchsticks.begin() , matchsticks.end() , cmp) ;
return solve(matchsticks , 0 , s / 4) ;
}
};
773. 滑动谜题
https://leetcode.cn/problems/sliding-puzzle/description/
思路:因为只有六个方块,其实状态不是特别多,并且问题问的是最少通过多少次转移,就很像最短路。于是用字符串来保存状态,然后去求最短路。
代码:
unordered_map<string, int> vis ;
unordered_map<string, int> dist ;
vector<string> V ;
int dirx[] = {0 , 1 , 0 , -1} ;
int diry[] = {1 , 0 , -1 , 0} ;
void spfa(string sta) {
vis[sta] = 1 ;
dist[sta] = 0 ;
queue<string> Q ;
Q.push(sta) ;
while (!Q.empty()) {
string nowstr = Q.front() ;
Q.pop() ;
vis[nowstr] = 0 ;
// 从数字还原二维数组
V.clear() ;
string s1 = nowstr.substr(0 , 3) ;
string s2 = nowstr.substr(3) ;
V.push_back(s1) ;
V.push_back(s2) ;
string kaka = V[0] + V[1] ;
int nowx = 0 ;
int nowy = 0 ;
for (int i = 0 ; i < V.size() ; ++i) {
for (int j = 0 ; j < 3 ; ++j) {
if (V[i][j] == '0') {
nowx = i ;
nowy = j ;
}
}
}
for (int i = 0 ; i < 4 ; ++i) {
int newx = dirx[i] + nowx ;
int newy = diry[i] + nowy ;
if (newx < 0 || newy < 0 || newx == 2 || newy == 3) {
continue ;
}
kaka = V[0] + V[1] ;
// 交换位置
char yo ;
yo = V[newx][newy] ;
V[newx][newy] = V[nowx][nowy] ;
V[nowx][nowy] = yo ;
kaka = V[0] + V[1] ;
// 记录
string newstr = V[0] + V[1] ;
// 没有插入过
if (dist.find(newstr) == dist.end()) {
dist[newstr] = dist[nowstr] + 1 ;
Q.push(newstr) ;
vis[newstr] = 1 ;
}
// 插入过
else {
if(dist[nowstr] + 1 < dist[newstr]) {
dist[newstr] = dist[nowstr] + 1 ;
if (vis[newstr] == 0) {
Q.push(newstr) ;
vis[newstr] = 1 ;
}
}
}
// 再换回来
yo = V[newx][newy] ;
V[newx][newy] = V[nowx][nowy] ;
V[nowx][nowy] = yo ;
string kaka = V[0] + V[1] ;
}
}
}
class Solution {
public:
int slidingPuzzle(vector<vector<int>>& board) {
vis.clear() ;
dist.clear() ;
string yoho = "" ;
for (int i = 0 ; i < board.size() ; ++i) {
for (int j = 0 ; j < board[0].size() ; ++j) {
yoho = yoho + char(board[i][j] + '0') ;
}
}
spfa(yoho) ;
if (dist.find("123450") == dist.end()) {
return -1 ;
}
else {
return dist["123450"] ;
}
}
};