1. 程式人生 > 實用技巧 >[LeetCode] 617. Merge Two Binary Trees(合併兩棵二叉樹)

[LeetCode] 617. Merge Two Binary Trees(合併兩棵二叉樹)

Description

Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not.

給你兩棵二叉樹,想象一下,當你把其中一棵樹置於另一棵樹之上時,其中的一部分節點會互相覆蓋,另外一些節點則不會。

You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree.

你需要把這兩棵二叉樹合併為一棵新的二叉樹。合併規則是:如果兩個節點互相覆蓋,取這兩個節點值的和作為新節點的值;否則,取非空的節點的值作為新節點的值。

Examples

Example 1

Input: 
    Tree 1                     Tree 2                  
          1                         2                             
         / \                       / \                            
        3   2                     1   3                        
       /                           \   \                      
      5                             4   7                  
Output: 
Merged tree:
         3
        / \
       4   5
      / \   \ 
     5   4   7

Note

The merging process must start from the root nodes of both trees.

合併過程都是從兩節點的根開始的。

Solution

此題的解題思路來自於題目中對於合併規則的描述。按照合併規則的描述,可以很容易地寫出合併根節點的程式碼,然後再通過對左右子樹遞迴呼叫方法,來實現對左右子樹的合併,最後完成此題。

/**
 * Example:
 * var ti = TreeNode(5)
 * var v = ti.`val`
 * Definition for a binary tree node.
 * class TreeNode(var `val`: Int) {
 *     var left: TreeNode? = null
 *     var right: TreeNode? = null
 * }
 */
class Solution {
    fun mergeTrees(t1: TreeNode?, t2: TreeNode?): TreeNode? {
        // 對空樹的處理:一個為空就返回另一個
        if (t1 == null) {
            return t2
        }
        if (t2 == null) {
            return t1
        }
        // 兩個均為非空,則先將樹根的值進行合併
        val newNode = TreeNode(t1.`val` + t2.`val`)
        // 然後依次對左子樹和右子樹以相同的方式處理
        newNode.left = mergeTrees(t1.left, t2.left)
        newNode.right = mergeTrees(t1.right, t2.right)
        return newNode
    }
}

上面的程式碼雖然能夠解決問題,但就我個人認為,這個解法不應該對原先傳入的樹造成影響。上面的程式碼會存在一種情況:新的節點的 leftright 指標可能會指向原樹中的某一個節點。利用 Kotlin 的語法特性,可以得到本題的另一種寫法,雖然未經測試,但目測來看應該解決了這一問題:

/**
 * Example:
 * var ti = TreeNode(5)
 * var v = ti.`val`
 * Definition for a binary tree node.
 * class TreeNode(var `val`: Int) {
 *     var left: TreeNode? = null
 *     var right: TreeNode? = null
 * }
 */
class Solution {
    fun mergeTrees(t1: TreeNode?, t2: TreeNode?): TreeNode? {
        // 對兩棵樹均為空樹的特判
        if (t1 == null && t2 == null) {
            return null
        }
        // 思路與剛才相同,但利用 Kotlin 的語法糖少寫一些 if 判斷
        val lVal = t1?.`val`?:0
        val rVal = t2?.`val`?:0
        val newRoot = TreeNode(lVal + rVal)
        newRoot.left = mergeTrees(t1?.left, t2?.left)
        newRoot.right = mergeTrees(t1?.right, t2?.right)
        return newRoot
    }
}