問題描述
給定兩顆平衡的有序二叉樹,要求將這兩個二叉樹合並為一個平衡的有序二叉樹。
問題解答
假定兩個數的結點數分別為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; }