1. 程式人生 > >二叉樹葉子節點的處理

二叉樹葉子節點的處理

         其實對於葉子節點的處理,依舊是通過遍歷進行處理,往往使用先序遍歷並稍加改動即可,在進行先序遍歷時,首先處理中間節點,但進行判斷,若是葉子節點,則進行符合題目要求邏輯的處理,若不是葉子節點則不處理;然後遞迴呼叫處理其左右子樹。

         對於遞迴遍歷方法,要多多品味,比較有意思,什麼時候停止,每一次進行了什麼處理並會產生什麼影響,這些是遞迴中需要思考的。

1、leetcode872題

題目描述:

請考慮一顆二叉樹上所有的葉子,這些葉子的值按從左到右的順序排列形成一個 葉值序列

 。

舉個例子,如上圖所示,給定一顆葉值序列為 (6, 7, 4, 9, 8) 的樹。

如果有兩顆二叉樹的葉值序列是相同,那麼我們就認為它們是 葉相似 的。

如果給定的兩個頭結點分別為 root1 和 root2 的樹是葉相似的,則返回 true;否則返回 false 。

提示:

  • 給定的兩顆樹可能會有 1 到 100 個結點。

解決思路及程式碼:

class Solution {
    //通過先序遍歷處理所有的節點,判斷當前節點是否為葉子節點,並將葉子節點加入儲存值的字串中
    //先序遍歷,先處理中間節點,後處理左右子樹
    //處理中間節點時並非將所有的中間節點進行處理,此處需要對先序遍歷稍加改動,只處理葉子節點
    public boolean leafSimilar(TreeNode root1, TreeNode root2) {
        String sr1 = leaf(root1);
        String sr2 = leaf(root2);
        return sr1.equals(sr2);
    }
    //該方法得到一顆樹的葉值序列
    private String leaf(TreeNode root){
        //遞迴深層處結束退出
        if(root == null){
            return null;
        }
        //先序遍歷處理當前節點
        String result = "";
        if(root.left == null && root.right == null){
            result += root.val;
        }
        //先序遍歷處理左右子樹
        if(root.left != null){
            result += leaf(root.left);
        }
        if(root.right != null){
            result += leaf(root.right);
        }
        
        return result;
    }
}

2.leetcode404題

題目描述:

計算給定二叉樹的所有左葉子之和。

示例:

    3
   / \
  9  20
    /  \
   15   7

在這個二叉樹中,有兩個左葉子,分別是 9 和 15,所以返回 24

解決思路及程式碼:

class Solution {
    //如何判斷一個節點是左葉子節點呢
    //首先想到如果直接看一個節點,由於樹的向下可查,向上不可查的特性,是沒有辦法直接判斷出一個節點是左葉子節點的
    //仔細想一下,如果看該節點的父節點就可以判斷該節點是否為左葉子節點了
    //因此判斷一個節點時,應從其父節點入手
    //每次處理的當前節點,判斷其左子節點是否為葉子節點,即可實現尋找左子節點
    public int sumOfLeftLeaves(TreeNode root) {
        int sum = 0;
        
        if(root != null){
            //root的左子節點不為空
            if(root.left != null){
                //root的左子節點為葉子節點
                if(root.left.left == null && root.left.right == null){
                    sum += root.left.val;
                }
                //root的左子節點非葉子節點,遞迴處理root的左子節點
                sum += sumOfLeftLeaves(root.left);
                
            }
            //root的右子節點不為空
            if(root.right != null){
                //遞迴處理root的右子節點
                sum += sumOfLeftLeaves(root.right);
            }
            
        }
        
        return sum;
    }
}