---
# System prepended metadata

title: 1305. All Elements in Two Binary Search Trees
tags: [Leetcode, FaceBook, DFS, Medium]

---

# 1305. All Elements in Two Binary Search Trees
###### tags: `Leetcode` `Medium` `FaceBook` `DFS`
Link: https://leetcode.com/problems/all-elements-in-two-binary-search-trees/
## 思路 $O(M+N)$ $O(M+N)$
### iterative one pass
和inorder traversal的iterative版差不多，拿到一个node，先找到最左边的（过程中把经历过的node放进stack），然后比较栈顶元素，某个元素pop出来之后先把值加进list，然后遍历当前node的right child
### recursive two pass
首先把两个tree inorder traversal，得到两个排好序的list/arr，然后再把他们merge起来就是答案
一开始的merge想法是用[0088. Merge Sorted Array](https://hackmd.io/uNTJQ2RaRAWsjYu7prqQlQ)，但其实这道题已经不追求O(1)了，因此可以再建一个array存结果，不需要用那道题的方法
但是实作的时候还是有一个点值得注意，因为写的时候是合并两个list，所以需要先指定答案list的长度，这样才能从后往前加，但是如果把line7写成
```List<Integer> ans = new ArrayList<>(list1.size()+list2.size())```
会发现ans的长度还是0，因此后面插入的时候就会有问题,因此**想要指定list长度，一定要用
```List<Integer> ans = Arrays.asList(new Integer[list1.size()+list2.size()]);```
后面用set放元素进去，而不是add**
## Code
### iterative one pass
```java=
class Solution {
    public List<Integer> getAllElements(TreeNode root1, TreeNode root2) {
        List<Integer> ans = new ArrayList<>();
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        while(root1!=null || root2!=null || !stack1.isEmpty() || !stack2.isEmpty()){
            while(root1!=null){
                stack1.push(root1);
                root1 = root1.left;
            }
            while(root2!=null){
                stack2.push(root2);
                root2 = root2.left;
            }
            if(stack2.isEmpty() || !stack1.isEmpty() &&stack1.peek().val<=stack2.peek().val){
                root1 = stack1.pop();
                ans.add(root1.val);
                root1 = root1.right;
            }
            else if(stack1.isEmpty() || stack2.peek().val<stack1.peek().val){
                root2 = stack2.pop();
                ans.add(root2.val);
                root2 = root2.right;
            }
        }
        return ans;
    }
}
```
### recursive two pass
```java=
class Solution {
    public List<Integer> getAllElements(TreeNode root1, TreeNode root2) {
        List<Integer> list1 = new ArrayList<>();
        inorder(root1, list1);
        List<Integer> list2 = new ArrayList<>();
        inorder(root2, list2);
        List<Integer> ans = Arrays.asList(new Integer[list1.size()+list2.size()]);
        int idx1 = list1.size()-1;
        int idx2 = list2.size()-1;
        int idx = list1.size()+list2.size()-1;
        while(idx1>=0 && idx2>=0){
            if(list1.get(idx1)>list2.get(idx2)){
                ans.set(idx, list1.get(idx1));
                idx1--;
            }
            else{
                ans.set(idx, list2.get(idx2));
                idx2--;
            }
            idx--;
        }
        while(idx2>=0){
            ans.set(idx, list2.get(idx2));
            idx2--;
            idx--;
        }
        while(idx1>=0){
            ans.set(idx, list1.get(idx1));
            idx1--;
            idx--;
        }
        return ans;
    }
    public void inorder(TreeNode root, List<Integer> arr){
        if(root==null) return;
        inorder(root.left, arr);
        arr.add(root.val);
        inorder(root.right, arr);
    }
}
```