LeetCode96:Unique Binary Search Trees

2443 단어 LeetCode
Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
For example, Given n = 3, there are a total of 5 unique BST's.
   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

n을 정하고 1부터 n까지 이 수를 구하면 몇 그루의 두 갈래 나무를 구성할 수 있습니까?
시퀀스 1을 지정합니다......n, 모든 두 갈래 나무를 구성하기 위해 우리는 1...n의 모든 수 i는 루트 노드로 자연 1...(i-1) 반드시 나무의 왼쪽 하위 트리에 위치하고 (i+1)......n은 트리의 오른쪽 하위 트리에 있습니다.그리고 좌우 트리를 차례로 구축할 수 있다. 뿌리 노드가 유일하기 때문에 구축된 두 갈래 트리가 모두 유일하다는 것을 보장할 수 있다.
두 가지 상태를 사용하여 기록합니다.
G(n): 길이가 n인 시퀀스의 모든 유일한 두 갈래 나무.
F(i, n), 1<=i<=n: i를 뿌리 노드로 하는 두 갈래 나무의 수량.
G(n)는 바로 우리가 요구하는 해답이다. G(n)는 F(i, n)로 계산할 수 있다.
G(n)=F(1,n)+F(2,n)+...+F(n,n)                      (1)
G(0)=1,G(1)=1
주어진 서열 1에 대해...n, 우리는 i를 그 뿌리 노드로 취한다. 그러면 i를 뿌리 노드로 하는 두 갈래 나무의 수량 F(i)는 아래의 공식으로 계산할 수 있다.
F(i,n)=G(i-1)*G(n-i) 1<=i<=n                         (2)
공식(1)과 공식(2)을 종합하면 다음과 같다.
G(n) = G(0) * G(n-1) + G(1) * G(n-2) + … + G(n-1) * G(0)
이것이 바로 위의 이 문제의 답안이다.
참조:https://leetcode.com/discuss/24282/dp-solution-in-6-lines-with-explanation-f-i-n-g-i-1-g-n-i
이 문제는 피폴라도 수열과 마찬가지로 귀속구해를 사용할 수도 있고 귀속구해를 사용하지 않을 수도 없지만 leetcode에서 귀속구해를 사용하면 시간을 초과할 수 있음을 알 수 있다.하지만 집행 결과는 옳았다.

해법 1: 귀속 해법


runtime:0ms
class Solution {
public:   
     int numTrees(int n) {
        if(n==0||n==1)
            return 1;
        
        int result=0;
        for(int i=0;i

해법2: 비귀속 해법

class Solution {
public:
    int numTrees(int n) {
        int *G=new int[n+1]();
        G[0]=1;
        G[1]=1;
        for(int i=2;i<=n;i++)
        {
            for(int j=0;j

해법3: 수학 공식


수학에는 카탈란(Catalan)이 있습니다.
h(0)=1, h(1)=1, 카타란 수 충족 귀속식:
h(n)= h(0)*h(n-1) + h(1)*h(n-2) + ... + h(n-1)h(0)(그중 n>=2), 이것은 n 단계 귀속 관계이다.
이 추이 관계의 해답은 h(n)=C(2n, n)/(n+1)=P(2n, n)/(n+1)!=(2n)!/(n!*(n+1)!) (n=1,2,3,...)
그래서 이 귀속 공식을 직접 사용하여 해답을 구할 수 있다.
class Solution {
public:
     int numTrees(int n) {
        long long ans=1;
        for(int i=n+1;i<=2*n;i++)
        {
            ans=ans*i/(i-n);
        }
        return ans/(n+1);
         
     }

};

좋은 웹페이지 즐겨찾기