Algorithm/LeetCode
[LeetCode # 95] Unique Binary Search Trees II
꼽냥이
2021. 9. 3. 14:21
반응형
주어진 문제는 위와 같다. 트리 노드의 개수인 n 이 주어지면, n 개의 노드를 갖는 BST 들을 찾는 것이다. 이 때, n 개의 노드들은 각각 1 부터 n 까지의 값을 갖는다.
BST (Binary Search Tree) 는 기본적으로 각 서브트리에서 루트 노드보다 작은 값들만 루트 노드의 Left 서브 트리에 저장될 수 있고, 루트 노드보다 큰 값들만 루트 노드의 Right 서브 트리에 저장될 수 있다는 특징을 갖는다.
이러한 특징을 기반으로 재귀를 활용해 문제를 풀이했다. 풀이 방식은 각 재귀 단계마다 BST 를 구성하려는 값의 범위 start ~ end 가 주어지고 그 범위 내의 값들을 루트 노드로 하는 BST 를 찾는 것이다.
간단한 슈도 코드로 이를 표현하자면, 다음과 같다.
recursiveBST(start, end):
for i in (start, end):
leftLists <- recursive_bst(start, i - 1)
rightLists <- recursive_bst(i + 1, end)
for left in leftLists:
for right in rightLists:
root <- new node(i)
root.left <- left
root.right <- right
(start, end) 범위 내에서 각각의 값을 갖는 노드를 루트 노드로 구성하고, 그 값보다 작은 값들을 갖는 서브 트리들과 그 값보다 큰 값들을 갖는 서브 트리들을 각각 루트 노드의 왼쪽 서브 트리, 오른쪽 서브 트리로 구성한다.
이러한 풀이 방식을 바탕으로 작성한 소스 코드는 다음과 같다.
class Solution {
public:
vector<TreeNode*> generateTrees(int start, int end) {
vector<TreeNode*> binarySearchTrees;
if (start > end) {
binarySearchTrees.push_back(NULL);
return binarySearchTrees;
}
if (start == end) {
binarySearchTrees.push_back(new TreeNode(start));
return binarySearchTrees;
}
for (int i = start; i <= end; i++) {
vector<TreeNode*> leftList = generateTrees(start, i - 1);
vector<TreeNode*> rightList = generateTrees(i + 1, end);
for (int l = 0; l < leftList.size(); l++) {
for (int r = 0; r < rightList.size(); r++) {
TreeNode* root = new TreeNode(i);
root->left = leftList[l];
root->right = rightList[r];
binarySearchTrees.push_back(root);
}
}
}
return binarySearchTrees;
}
vector<TreeNode*> generateTrees(int n) {
return generateTrees(1, n);
}
};