题目来源
题目来源
题目解析
递归
我们先来做一个基础题:如何求解整个树的节点和。
- 其递归公式: sum(root) = root.val + sum(root.left) + sum(root.right);
int sum(TreeNode* root) {
if (root == NULL) return 0;
return root->val + sum(root->left) + sum(root->right);
}
那么如何求坡度呢?根据题意:
- 当前节点的坡度: po(root) = abc(sum(root.left) - sum(root.right));
- 整个树的坡度 : po(root) + po(root.left) + po(root.left);
int sum(TreeNode* root){
if(root == NULL){
return 0;
}
return root->val + sum(root->left) + sum(root->right);
}
int findTilt(TreeNode* root) {
if(root == NULL){
return 0;
}
int left = sum(root->left);
int right = sum(root->right);
return std::abs(left - right) + findTilt(root->left) + findTilt(root->right);
}
但是,由于每次findTilt都会产生一次对sum的调用;整体的复杂度直接上升一个数量级,这是不可接受的,一个方案是加上记忆化。这样同样节点的sum就只会计算一次了;但也谈不上多优雅。
更好的方式是,我们可以一次递归来搞定,求和的同时把坡度也记录下来。由于c++只能返回一个参数,所以我们需要把子节点和的状态作为函数参数在递归中传递。
// 待优化