Given a binary tree, return the tilt of the whole tree.
The tilt of a tree node is defined as the absolute difference between the sum of all left subtree node values and the sum of all right subtree node values. Null node has tilt 0.
The tilt of the whole tree is defined as the sum of all nodes' tilt.
Example:
Input: 1 / \ 2 3 Output: 1 Explanation: Tilt of node 2 : 0 Tilt of node 3 : 0 Tilt of node 1 : |2-3| = 1 Tilt of binary tree : 0 + 0 + 1 = 1
Note:
- The sum of node values in any subtree won't exceed the range of 32-bit integer.
- All the tilt values won't exceed the range of 32-bit integer.
思路:
这道题要求求出每个节点的坡度(每个节点的左右节点和的差值的绝对值)的和。
我们把这道题的问题分解下,思路会清晰一些,首先对每个节点的左右子树求和(包括自身root的值),然后再求差值,所以直观想法是我们需要两个map,一个是m_sum用来记录每个节点的左右节点和自身的值的和,类似于求该节点为根节点的子树的权值和(包含根节点),另一个是m_res用来求该节点的左右节点的和的差值即:
e_res[root]=abs(m_sum[root-Left]-m_sum[root->right])
于是我们可以遍历三次(最笨的方法)
第一次遍历求每个节点的m_sum。
第二次遍历求每个节点的m_res。
第三次遍历累加每个节点的m_res。
但是我们把三次遍历放到一次遍历中,先计算m_sum,然后是m_res,最后累加m_res。于是得到如下代码:
void findTiltCore(TreeNode* root, map<TreeNode*, int> &m_sum, map<TreeNode*, int> &m_res,int &res) {
if (!root) {
return;
}
findTiltCore(root->left, m_sum, m_res, res);
findTiltCore(root->right, m_sum, m_res, res);
m_sum[root] = m_sum[root->left] + m_sum[root->right] + root->val;
int diff = m_sum[root->left] - m_sum[root->right];
m_res[root] = (diff) > 0 ? diff : (-diff);
res += m_res[root];
}
int findTilt(TreeNode* root) {
if (!root) {
return 0;
}
if (root && !root->left && !root->right) {
return 0;
}
map<TreeNode*, int> m_sum;
map<TreeNode*, int> m_res;
int res = 0;
findTiltCore(root, m_sum, m_res, res);
return res;
}
方法2:
提交后时间有点堪忧,分析原因是空间复杂度用了O(2n),并且每次读写map有内存开销。考虑到我们每次只需要上一次的sum和res值,所以把map去掉。用一个变量不断接受子节点传回的sum值并左右累加并加上自身后又返回给父节点,得到如下代码:
void findTiltCore(TreeNode* root, int &sum, int &res) {
if (!root) {
return;
}
int left = 0;
int right = 0;
findTiltCore(root->left, left, res);
findTiltCore(root->right, right, res);
int diff = left - right;
sum = left + right + root->val;
res += (diff>0) ? diff : (-diff);
}
int findTilt(TreeNode* root) {
if (!root) {
return 0;
}
if (root && !root->left && !root->right) {
return 0;
}
int sum = 0;
int res = 0;
findTiltCore(root, sum, res);
return res;
}
时间效率的提升还是很明显的: