解题思路
一棵保存信息的树如何去递归?
- 分析单独的子树要进行什么操作
- 分析这颗子树要返回什么东西
示例
1、二叉树的直径
- 每一棵子树的直径是其子树+1
- 返回的当前结点的直径(左边的直径和右边的直径取最大)
2、二叉树的最大路径和
- 每一棵子树的路径和max(左孩子路径和,有孩子路径和)+根节点的值,如果左孩子或者有孩子路径和为负数,则直接砍掉不要
- 返回当前子树的最大路径和
代码如下
class Solution {
public:
int ans = 0;
int dfs(TreeNode* root) {
if(!root)return -1;
int l = dfs(root->left) + 1;
int r = dfs(root->right) + 1;
ans = max(ans, l + r);
return max(l,r);
}
int diameterOfBinaryTree(TreeNode* root) {
dfs(root);
return ans;
}
};
class Solution {
public:
int ans;
int dfs(TreeNode* root){
if(!root)return 0;
//计算左子树
int l = dfs(root->left);
if(l < 0)l = 0;//如果小于0就直接砍掉
//计算右子树
int r = dfs(root->right);
if(r < 0)r = 0;
ans = max(ans,l + r + root->val);
//对于这棵子树的返回
return max(l + root->val,r + root->val);
}
int maxPathSum(TreeNode* root) {
ans = INT_MIN;
dfs(root);
return ans;
}
};
解题思路
1、每一棵子树需要去做什么?
- 如果符合条件,当前树的路径长 = 子树的路径长+1
2、当前这棵树返回的是什么?
- 返回的是当前树的最长路径=所有符合条件的子树中的最长路径
maxLen = max(maxLen,len + 1);//挑选最长的子树
class Solution {
public:
int longestPath(vector<int>& par, string s) {
int n = par.size();
vector<vector<int>> g(n);//保存的是每个结点的子节点是什么
for(int i = 1; i < n; ++i) {
g[par[i]].push_back(i);
}
int ans = 1;
function<int(int)> dfs = [&](int u)->int {
int maxLen = 1;//如果是叶子节点就返回1
for (int y : g[u]) {
int len = dfs(y);//子树的路径长度
if (s[y] != s[u]) {//只有不相等的时候才更新路径长度
ans = max(ans,maxLen + len);//如果当前就是答案,保存答案
maxLen = max(maxLen,len + 1);//挑选最长的子树
}
}
return maxLen;//返回的是当前树的路径长度
};
dfs(0);
return ans;
}
};