Hard
You are given n
BST (binary search tree) root nodes for n
separate BSTs stored in an array trees
(0-indexed). Each BST in trees
has at most 3 nodes, and no two roots have the same value. In one operation, you can:
i
and j
such that the value stored at one of the leaves of trees[i]
is equal to the root value of trees[j]
.trees[i]
with trees[j]
.trees[j]
from trees
.Return the root of the resulting BST if it is possible to form a valid BST after performing n - 1
operations, or null
if it is impossible to create a valid BST.
A BST (binary search tree) is a binary tree where each node satisfies the following property:
A leaf is a node that has no children.
Example 1:
Input: trees = [[2,1],[3,2,5],[5,4]]
Output: [3,2,5,1,null,4]
Explanation: In the first operation, pick i=1 and j=0, and merge trees[0] into trees[1]. Delete trees[0], so trees = [[3,2,5,1],[5,4]]. In the second operation, pick i=0 and j=1, and merge trees[1] into trees[0]. Delete trees[1], so trees = [[3,2,5,1,null,4]]. The resulting tree, shown above, is a valid BST, so return its root.
Example 2:
Input: trees = [[5,3,8],[3,2,6]]
Output: []
Explanation: Pick i=0 and j=1 and merge trees[1] into trees[0]. Delete trees[1], so trees = [[5,3,8,2,6]]. The resulting tree is shown above. This is the only valid operation that can be performed, but the resulting tree is not a valid BST, so return null.
Example 3:
Input: trees = [[5,4],[3]]
Output: []
Explanation: It is impossible to perform any operations.
Constraints:
n == trees.length
1 <= n <= 5 * 104
[1, 3]
.trees
have the same value.1 <= TreeNode.val <= 5 * 104
.import com_github_leetcode.TreeNode;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
public class Solution {
private static final Map<Integer, TreeNode> ROOT_VALS = new HashMap<>();
public TreeNode canMerge(List<TreeNode> trees) {
TreeNode root = findRoot(trees);
if (root == null) {
return null;
}
for (TreeNode t : trees) {
ROOT_VALS.put(t.val, t);
}
bfs(root);
if (!isValidBST(root) || ROOT_VALS.size() != 1) {
return null;
}
return root;
}
private TreeNode findRoot(List<TreeNode> trees) {
TreeNode root = null;
Map<Integer, Integer> valCnts = new HashMap<>();
for (TreeNode t : trees) {
valCnts.put(t.val, valCnts.getOrDefault(t.val, 0) + 1);
if (t.left != null) {
valCnts.put(t.left.val, valCnts.getOrDefault(t.left.val, 0) + 1);
}
if (t.right != null) {
valCnts.put(t.right.val, valCnts.getOrDefault(t.right.val, 0) + 1);
}
}
for (TreeNode t : trees) {
if (valCnts.get(t.val) == 1) {
if (root == null) {
root = t;
} else {
return null;
}
}
}
return root;
}
private void bfs(TreeNode root) {
Queue<TreeNode> q = new ArrayDeque<>();
q.offer(root);
while (!q.isEmpty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
TreeNode parent = q.poll();
if (parent.left != null && ROOT_VALS.containsKey(parent.left.val)) {
TreeNode toConnect = ROOT_VALS.get(parent.left.val);
ROOT_VALS.remove(toConnect.val);
parent.left = toConnect;
q.offer(parent.left);
}
if (parent.right != null && ROOT_VALS.containsKey(parent.right.val)) {
TreeNode toConnect = ROOT_VALS.get(parent.right.val);
ROOT_VALS.remove(toConnect.val);
parent.right = toConnect;
q.offer(parent.right);
}
}
}
}
private boolean isValidBST(TreeNode root) {
return isValidBST(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
private boolean isValidBST(TreeNode root, int min, int max) {
if (root == null) {
return true;
}
if (root.val <= min || root.val >= max) {
return false;
}
return isValidBST(root.left, min, root.val) && isValidBST(root.right, root.val, max);
}
}