这也是看的灵茶山艾府 b站视频:看到递归就晕?带你理解递归的本质!【基础算法精讲 09】+ 如何灵活运用递归?【基础算法精讲 10】 这俩个视频的观后感。最大的感悟是 从上至下的掌法 太帅太酷啦。
目标:培养从根节点开始看起的思维方式。
模版:
b站回溯视频 一般情况下 我怎么思考:
一般情况下 我的回溯问题 都是从下到上:前序遍历怎么遍历,我怎么思考这个问题。
在实际情况中,有一种对于回溯问题更好解更减少思考成本的思考方式:从上至下的思考方式:
root 为 1 维护全局变量,更新全局变量的最大值,最后返回全局变量。
这就是个好用的模版。对于我来说 tree的做法 从上至下更好思考。
我不喜欢叫这种解回溯 感觉和先xu遍历分不开 能不能帮我想个好名字
class Solution { int min_e = INT_MAX; void dfs(TreeNode* root, int dep){ if(!root){ min_e = min(min_e, dep); return; } dfs(root->left, dep+1); dfs(root->right, dep + 1); } public: int maxDepth(TreeNode* root) { if(!root) return 0; dfs(root, 1); return min_e; } };
从下至上法
class Solution { public: int maxDepth(TreeNode* root) { if(!root) return 0; return max(maxDepth(root->left), maxDepth(root->right))+1; } };
从上至下的模版:
维护全局变量,从上至下的思考,假设到了叶子节点-》怎么处理, 然后直接dfs(root->left) dfs(root->right)
class Solution {
int ans = 0;
void dfs(TreeNode* root, int **, int**){
if(!root) // if(!root->left && !root->right){} 后者情况需要加上if(root->left, root->right)//base case 叶子节点一定是base case 很多时候 用if(!root)只是因为如果非叶子节点,仅是某个节点的空左节点,空右节点,不影响回溯答案。 但叶子节点 一定是base case 如果走的是叶子节点的思考路径 那么一定要加上 if(root->left) dfs(); if(root->right) dfs(); 防止溢出。
dfs(root->left,...);
dfs(root->right,...);
}
public:
int maxAncestorDiff(TreeNode* root) {
if(!root) return ...
dfs(root, asdlkj);
return ans;// return 全局变量
}
};
例题: 111. 二叉树的最小深度
class Solution {
int min_d = INT_MAX;
void dfs(TreeNode* root, int depth){
if(!root->left && !root->right){
min_d = min(min_d, depth);
return;
}
if(root->left) dfs(root->left, depth+1);
if(root->right) dfs(root->right, depth+1);
}
public:
int minDepth(TreeNode* root) {
if(!root) return 0;
dfs(root, 1);
return min_d;
}
};
leetcode 1026:
class Solution {
int ans = 0;
void findAns(TreeNode* root, int mn, int mx){
mn = min(root->val, mn);
mx = max(root->val, mx);
if(!root->left && !root->right){
ans = max(ans, mx - mn);
return;
}
if(root->left) findAns(root->left, mn, mx);
if(root->right) findAns(root->right, mn, mx);
}
public:
int maxAncestorDiff(TreeNode* root) {
if(!root) return 0;
findAns(root, root->val, root->val);
return ans;
}
};
LeetCode 98
灵神提供的思路 但我的写法比灵神简单干净利落 oh yeah。 注意范围LLONG_MIN, LLONG_MAX;
class Solution {
bool beAGoodTree(TreeNode* root, long long mn, long long mx){
if(!root) return true;
if(root->val >= mx || root->val <= mn) return false;
return beAGoodTree(root->right, root->val, mx) && beAGoodTree(root->left, mn, root->val);
}
public:
bool isValidBST(TreeNode* root) {
return beAGoodTree(root, LLONG_MIN, LLONG_MAX);
}
};
微难题: leetcode 1080: 出的题目有点绕。