理解二叉樹遞迴中的自底向上和自頂向下兩種思想

尚墨1111發表於2020-12-18

前言:一直搞不清楚自頂向下自底向上的區別

下面從幾個例子來簡要分析


一、區分兩個概念:

自頂向下:直接return 函式呼叫自身下一級實現,比如 return Fibonacci(n-1) + Fibonacci(n-2);
自底向上:先遞迴到最小單位(葉子節點),再從最小單位往上拋結果,傳遞結果


二、具體事例分析:

/**
 * 兩種遍歷方向,計算最大深度
 * 自頂向下
 * 自底向上
 *
 * @Auther:sommer1111
 * @date 2020/11/10 19:05
 */
public class _11_10_Top_Down {

    //自頂向下
    private int answer;
    private void maximum_depth(TreeNode root, int depth) {
        if (root == null) {
            return;
        }
        if (root.left == null && root.right == null) {
            answer = Math.max(answer, depth);
        }
        maximum_depth(root.left, depth + 1);
        maximum_depth(root.right, depth + 1);
    }

    //自底向上
    public int maximum_depth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        //感受一下這裡是將最底層的結果往上拋
        //,因為這裡的遞迴邊界條件是葉子節點
        int left_depth = maximum_depth(root.left);
        int right_depth = maximum_depth(root.right);
        return Math.max(left_depth, right_depth) + 1;
    }
}

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 * LettCode中的題:
 * 235. 二叉搜尋樹的最近公共祖先
 * 236. 二叉樹的最近公共祖先
 */

class Solution {

	//搜尋二叉樹直接可以分為比大小,定位
    //分為都在左子樹、都在右子樹、兩邊(root)
    public TreeNode lowestCommonAncestor235(TreeNode root, TreeNode p, TreeNode q) {
        if(p.val<root.val && q.val<root.val){
        	//這裡就是自頂向下
            return lowestCommonAncestor235(root.left,p,q);
        }
        if(p.val>root.val && q.val>root.val){
            return lowestCommonAncestor235(root.right,p,q);
        }
        return root;
    }


    //遞迴自底向上,討論子樹中是否含有某個節點
    // 如果分別在左右子樹,則返回跟節點
    // 如果在同一個子樹繼續往下遞迴
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null ||root==p || root==q){
            return root;
        }else{
        //著也是自底向上的思想
            TreeNode left = lowestCommonAncestor(root.left,p,q);
            TreeNode right = lowestCommonAncestor(root.right,p,q);
            if(left==null && right==null){
                return null;
            }

            if(left==null){
                return right;
            }

            if(right==null){
                return left;
            }

            return root;

        }
    }
}

相關文章