1. 程式人生 > >【LeetCode】823. Binary Trees With Factors 解題報告(Python)

【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. 1 <= A.length <= 1000.
  2. 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 日 —— 啊,十月過完了