(Leetcode 刷题) 两颗二叉搜索树的所有元素※

题目描述

给你 root1 和 root2 这两棵二叉搜索树。
请你返回一个列表,其中包含 两棵树 中的所有整数并按 升序 排序。
1305. 两颗二叉搜索树的所有元素

解法1 中序遍历得到升序序列,再排序

我们知道了中序遍历的二叉搜索树的结果为非降序序列,将两个非降序序列排序,效率很低,毕竟最后都要排序,没必要追求非降序序列。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List getAllElements(TreeNode root1, TreeNode root2) {
        List list1 = new LinkedList<>();
        List list2 = new LinkedList<>();
        inorder(root1,list1);
        inorder(root2,list2);
        
        //排序
        List list = new ArrayList<>();
        int a = 0;
        int b = 0;
        for(int i = 0; i < list1.size() + list2.size(); i++){
            if(a tmp2){
                    list.add(tmp2);
                    b++;
                }else{
                    list.add(tmp1);
                    a++;
                }
            }
        }

        while( a < list1.size()){
            list.add(list1.get(a++));
        }

        while( b < list2.size()){
            list.add(list2.get(b++));
        }
        return list;
    }

    public void inorder(TreeNode root, List list ){
        if(root == null){
            return;
        }
        inorder(root.left,list);
        list.add(root.val);
        inorder(root.right,list);
    }
}

解法2 遍历两棵树,再排序

与上面的区别是遍历时不在乎顺序,到最后一步统一排序。

class Solution {
    //遍历两棵树,把结果放在res里
    List res = new ArrayList<>();
    public List getAllElements(TreeNode root1, TreeNode root2) {  
         get(root1);
         get(root2);
         //直接调用封装好的排序
         Collections.sort(res);
         return res;
    }
    private void get(TreeNode root){
        if(root != null){
            res.add(root.val);
            get(root.left);
            get(root.right);
        }
    }
}

解法3 在树的遍历的过程中进行排序

先遍历得到一棵树的非降序排序(中序遍历),遍历第二棵树的时候排序得到最终结果。

遍历第一棵树得到一个叫res1的队列,res1中是非降序的。
遍历第二棵树的第一个节点(中序遍历第一个节点是最小的节点)的时候,判断遍历到的节点值与res1的最小值的大小。如果res1中的元素小,将res1中比第二棵树最小节点还小的所有节点存入ans中(ans是一个存放最后结果的list),随后再存第一个节点。重复以上过程,可以得到含有全部第二棵树节点和(可能)部分第一棵树节点的list ans。
如果res1还有剩下的值,把这些值加在ans的后面,返回最终结果。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List getAllElements(TreeNode root1, TreeNode root2) {
        Queue res1 = new LinkedList<>();
        List ans = new LinkedList<>();
        helper(root1, res1);
        helper2(root2, res1, ans);
        //res1还有可能存在没有加入的节点,这些节点比第二棵树的最大结点还大
        while (!res1.isEmpty()) ans.add(res1.poll());
        return ans;
    }
    
    //中序遍历第一棵树
    private void helper(TreeNode node, Queue res) {
        if (node == null) return;
        helper(node.left, res);
        res.offer(node.val);
        helper(node.right, res);
    }
    
    //中序遍历第二棵树
    private void helper2(TreeNode node, Queue res, List ans) {
        if (node == null) return;
        helper2(node.left, res, ans);
        
        //res1中比当前遍历节点小的先加入ans中
        while (!res.isEmpty() && node.val > res.peek()) {
            ans.add(res.poll());
        }
        ans.add(node.val);

        helper2(node.right, res, ans);
    }
}

你可能感兴趣的:((Leetcode 刷题) 两颗二叉搜索树的所有元素※)