【LeetCode】823. Binary Trees With Factors 解題報告(Python)
目錄
題目描述
Given an array of unique integers, each integer is strictly greater than 1.
We make a binary tree using these integers and each number may be used for any number of times.
Each non-leaf node’s value should be equal to the product of the values of it’s children.
How many binary trees can we make? Return the answer modulo 10 ** 9 + 7
Example 1:
Input: A = [2, 4]
Output: 3
Explanation: We can make these trees: [2], [4], [4, 2, 2]
Example 2:
Input: A = [2, 4, 5, 10]
Output: 7
Explanation: We can make these trees: [2], [4], [5], [10], [4, 2, 2], [10, 2, 5], [10, 5, 2].
Note:
1 <= A.length <= 1000
.2 <= A[i] <= 10 ^ 9
.
題目大意
給定了一個數組,可以從這個陣列中選取任意多的節點構建成二叉樹,要求二叉樹中的非葉子節點的值必須等於其子節點的和。問有多少種組合方案。
解題方法
動態規劃
題目出現了DP的最最明顯提示:需要對結果求模!這個說明結果很大,必須通過DP求解了。
方法其實很簡單的,首先需要先排序,注意到題目中說了陣列是Unique的,所以每個數字出現的次數只有1次。使用dp陣列儲存每個數字作為根節點的情況下能構建出的所有二叉樹數目,求法是遍歷所有小於自己的數字取值作為左子樹,然後把根節點/左子樹的值當做右節點,然後對他們能組成的二叉樹數目乘積求和。
dp[i] = sum(dp[j] * dp[i / j]) res = sum(dp[i])
需要注意的是,一定要保證根節點/左子樹的結果是整數,而且也在dp內,才去做狀態轉移。因為,題目給的每個數字都是大於1的,因此根節點/左子樹一定小於根節點,所以直接判斷它是否在dp裡出現過就行了,它不可能在更後面才出現。
時間複雜度是O(NlogN + N),空間複雜度是O(N).
class Solution(object):
def numFactoredBinaryTrees(self, A):
"""
:type A: List[int]
:rtype: int
"""
A.sort()
dp = {}
for i, a in enumerate(A):
dp[a] = 1
for j in range(i):
if a % A[j] == 0 and a / A[j] in dp:
dp[a] += dp[A[j]] * dp[a / A[j]]
return sum(dp.values()) % (10**9 + 7)
相似題目
參考資料
日期
2018 年 10 月 30 日 —— 啊,十月過完了