Leetcode 823. 요인이 있는 이진 트리 [솔루션]
난이도: 보통
이동:
문제 설명
Question: https://leetcode.com/problems/binary-trees-with-factors/고유한 정수 배열
arr
이 주어지면 각 정수 arr[i]
는 엄격하게 1
보다 큽니다.우리는 이러한 정수를 사용하여 이진 트리를 만들고 각 숫자는 여러 번 사용할 수 있습니다. 리프가 아닌 각 노드의 값은 자식 값의 곱과 같아야 합니다.
우리가 만들 수 있는 이진 트리의 수를 반환합니다. 답이 너무 클 수 있으므로 답을 모듈로
109 + 7
로 반환합니다.예 1:
입력: arr = [2,4]
출력: 3
설명: 우리는 다음과 같은 나무를 만들 수 있습니다:
[2], [4], [4, 2, 2]
예 2:
입력: arr = [2,4,5,10]
출력: 7
설명: 다음 나무를 만들 수 있습니다:
[2], [4], [5], [10], [4, 2, 2], [10, 2, 5], [10, 5, 2]
.제약:
1 <= arr.length <= 1000
2 <= arr[i] <= 109
설명
First, we need to understand, what is a factor to a number. For a number n
, x
is a factor if n%x==0
so two numbers x
and y
can be children of n
in the binary tree, only if x * y = n
.
One small point to bring into notice: It's given that 2 <= arr[i]
because if arr[i]
is 0
or 1
then infinite solutions are possible.
So we need to find that how many such trees of any depth can be created using a given number in any quantity. for example, if given numbers are [2,4,5,10]
then 7
trees are possible as below:
[2] [4] [5] [10]
[4] [10] [10]
/ \ / \ / \
[2] [2] [5] [2] [2] [5]
해결책
We need to see this problem as a problem breakable into subproblems, like in the example [2,5,10,20]
we can see this problem broken into subproblems [2]
, [2,5]
, [2,5,10]
and then final problem [2,5,10,20]
. We will solve these subproblems in order and by finding the number of trees with an item as root which is just added in the current subproblem in comparison to the last subproblem i.e.
- We'll first find the number of trees with
2
as a root and no children options available i.e.1
. - Then the number of trees with
5
as a root and[2]
is available as children option i.e.1
. - Then the number of trees with
10
as a root and[2,5]
is available as children option i.e.3
. - Then the number of trees with
20
as a root and[2,5,10]
is available as children option i.e.7
.
All the trees possible are as below:
결국 우리는 문제에 대한 해결책을 얻기 위해 위의 트리 수를 모두 합산합니다. 우리는 동적 프로그래밍을 사용할 것입니다.
각 하위 문제에 대한 답을 얻기 위해 우리는
1
트리가 해당 요소만으로 가능하다는 논리를 사용하여 루트가 유일한 트리인 n
를 가정합니다. 그리고 n
의 인수인 각 요소에 대해 x
라고 가정해 봅시다(그리고 다른 하나는 y
입니다) 우리는 x
의 하위 솔루션과 y
의 하위 솔루션의 곱셈을 추가할 것입니다. 왼쪽 자식으로 한 번x
, 왼쪽 자식으로y
. 요소는 항상 실제 숫자보다 작기 때문에 배열을 먼저 정렬하므로 매번 전체 배열에서 요소를 찾을 필요가 없습니다. 현재 숫자가 정렬된 배열이 되기 전에 요소만 볼 수 있습니다.DP 방정식:
dp[i] = sum(dp[j] * dp[i / j])
ans = sum(dp[i])
코드를 보자. 더 명확해질 것이다.
구현
C++ Code:
#define MOD 1000000007
class Solution {
public:
int numFactoredBinaryTrees(vector<int>& arr) {
unordered_map<int,long int> dp;
int len=arr.size();
// Sorting array
sort(arr.begin(), arr.end());
for(int i=0;i<len;i++){
// One tree is always possible (root only)
dp[arr[i]] = 1;
// Check for all elements less than current element arr[i]
for(int j=0; j<i; j++){
// Check if arr[j] is factor of arr[i]
// and the second factor (arr[i]/arr[j]) is seen
if(arr[i]%arr[j]==0 && dp.find((arr[i]/arr[j]))!=dp.end()){
// Add combinations in dp with arr[j] as left child
// So (arr[i]/arr[j]) becomes right child automatically
dp[arr[i]] += (dp[arr[j]] * dp[(arr[i]/arr[j])]) % MOD;
dp[arr[i]] %= MOD;
}
}
}
int ans=0;
// Find sum of dp to sum solution of all subproblems
for(auto i : dp){
ans += i.second;
ans %= MOD;
}
return ans;
}
};
- Time Complexity:
O(N^2)
, whereN
is the length ofarr
. This comes from the two for-loops iteratingi
andj
. - Space Complexity:
O(N)
, the space used bydp
.
Runnable C++ code:
Reference
이 문제에 관하여(Leetcode 823. 요인이 있는 이진 트리 [솔루션]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/shivams136/leetcode-823-binary-trees-with-factors-solution-42a7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)