【樹】B043_LC_在二叉樹中分配硬幣(後序遍歷)

一、Problem

給定一個有 N 個結點的二叉樹的根結點 root,樹中的每個結點上都對應有 node.val 枚硬幣,並且總共有 N 枚硬幣。

在一次移動中,我們可以選擇兩個相鄰的結點,然後將一枚硬幣從其中一個結點移動到另一個結點。(移動可以是從父結點到子結點,或者從子結點移動到父結點。)。

返回使每個結點上只有一枚硬幣所需的移動次數。
在這裏插入圖片描述

輸入:[3,0,0]
輸出:2
解釋:從樹的根結點開始,我們將一枚硬幣移到它的左子結點上,一枚硬幣移到它的右子結點上。

在這裏插入圖片描述

輸入:[0,3,0]
輸出:3
解釋:從根結點的左子結點開始,我們將兩枚硬幣移到根結點上 [移動兩次]。然後,我們把一枚硬幣從根結點移到右子結點上。

提示:

1<= N <= 100
0 <= node.val <= N

二、Solution

方法一:後序遍歷

因爲我們要得到子節點的信息,所以後序遍歷最佳;又因爲最終的形狀是每個結點都只有 11 顆金幣,那假設某一個葉子結點 node 的金幣數爲 xx,則結點分配一顆金幣所需要的步驟數爲(x-1),x1x-1 的結果無外乎幾種:

  • x1=0x-1 = 0:表示該結點不需要分配金幣(已經有 1 顆金幣)
  • x1<0x-1 < 0:表示該結點沒有金幣,需要被分配
  • x1>0x-1 > 0:表示該結點的金幣數大於 11,此時也要將多餘的 x1x-1 顆硬幣移動

回到該葉子結點 node 的父親 fa,如果葉子結點需要的硬幣數爲 1,如果父親 fa 也沒有硬幣,那麼該父親 fa 向上傳遞的信息將會是 -2;但如果 fa 的右子節點有 2 個硬幣多餘,那麼 fa 向上傳遞的信息將會是 0

class Solution {
public:
	int op;
	int dfs(TreeNode* root) {
		if (root == NULL)
			return 0;
		int l = dfs(root->left), r = dfs(root->right), cur = l+r+root->val;
		op += abs(cur-1);
		return cur-1;
	}
    int distributeCoins(TreeNode* root) {
    	dfs(root);
    	return op;
    }
};

複雜度分析

  • 時間複雜度:O(n)O(n)
  • 空間複雜度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章