Binary Tree Tilt 二叉树的斜度

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:

  1. The sum of node values in any subtree won't exceed the range of 32-bit integer.
  2. 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;
   }

时间效率的提升还是很明显的:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值