合并两颗平衡有序二叉树

问题描述

给定两颗平衡的有序二叉树,要求将这两个二叉树合并为一个平衡的有序二叉树。

问题解答

假定两个数的结点数分别为m和n。

思路1

很容易想到把一颗树的每一个结点依次添加到另一颗树中,每次插入的平均时间复杂度为O(logn),在最坏情况下的插入时间复杂度为O(m + logn)。合并为一棵树的平均时间复杂度为O(mlog(m + n))。

单纯地将节点插入树中会破坏树的平衡性,因此之后需要将树展开为链表然后再生成平衡二叉树,时间复杂度为O(m + n)。

在插入过程中保持树的平衡性实现起来很困难,而且时间复杂度也会相应增加。

思路2:

考虑到结果二叉树是平衡的,因此将树展开然后生成平衡二叉树是无法避免的,因此可以考虑以下做法。

首先,将两棵树分别展开为有序链表,时间复杂度分别为O(m)和O(n);

    public TreeNode prev = null;
    public void BSTtoLinkedList(TreeNode root) {
        if (root == null) return;
        BSTtoLinkedList(root.left);
        if (prev != null) {
            prev.right = root;
            prev.left = null;
        }
        prev = root;
        BSTtoLinkedList(root.right);
    }

 

然后将两个有序链表合并,时间复杂度为O(m + n);

    public TreeNode MergeTwoLinkedList(TreeNode n1, TreeNode n2) {
        TreeNode head = new TreeNode();
        while (n1 != null && n2 != null) {
            if (n1.val < n2.val) {
                head.right = n1;
                n1 = n1.right;
            } else {
                head.right = n2;
                n2= n2.right;
            }
            head = head.right;
        }
        if (n1 != null) {
            head.right = n1;
            head = head.right;
        }
        if (n2 != null) {
            head.right = n2;
            head = head.right;
        }
        return head.right;
    }

 

最后把一个有序链表转化为一个平衡二叉树,时间复杂度为O(m + n)。

    public TreeNode LinkedListToBalancedBST(TreeNode root) {
        int num = 0;
        while (root != null) {
            num++;
            root = root.right;
        }
        return ListToBST(root, num);
    }
    public TreeNode cur = null;
    public TreeNode ListToBST(TreeNode root, int num) {
        if (num <= 0) return null;
        if (cur == null) cur = root;
        TreeNode left = ListToBST(root, num / 2);
        TreeNode temp = cur;
        cur = cur.right;
        temp.right = ListToBST(cur, num - 1 - num / 2);
        temp.left = left;
        return temp;
    }

 

转载于:https://www.cnblogs.com/shinning/p/6243503.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值