【Leetcode】366. Find Leaves of Binary Tree

題目地址:

https://leetcode.com/problems/find-leaves-of-binary-tree/

給定一棵二叉樹,每次蒐集其葉子的值,並把葉子刪掉,再重複這樣的操作直到整棵樹都變空爲止。

法1:多次遞歸,每次蒐集並且刪掉葉子的方法就是,如果走到了葉子,就將葉子加入列表,並返回null給上一層,連到進入這一層遞歸時的父親節點上。如此這樣直到整棵樹被刪乾淨爲止。代碼如下:

import java.util.ArrayList;
import java.util.List;

public class Solution {
    public List<List<Integer>> findLeaves(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        // 只有樹不空,就蒐集並刪除葉子,並將葉子加入res
        while (root != null) {
            List<Integer> leaves = new ArrayList<>();
            root = dfs(root, leaves);
            res.add(leaves);
        }
        
        return res;
    }
    
    // 返回刪掉root子樹葉子後的樹根
    private TreeNode dfs(TreeNode root, List<Integer> cur) {
        if (root == null) {
            return null;
        }
        
        // 遇到葉子,則加入cur列表中,並返回null,也就是將葉子刪掉
        if (root.left == null && root.right == null) {
            cur.add(root.val);
            return null;
        }
        
        // 將左右子樹葉子刪掉後返回刪掉葉子後的左右樹根,並連到原樹根上去
        root.left = dfs(root.left, cur);
        root.right = dfs(root.right, cur);
        return root;
    }
}

class TreeNode {
    int val;
    TreeNode left, right;
    TreeNode(int x) {
        val = x;
    }
}

時間複雜度O(n2)O(n^2),空間O(h)O(h)

對於滿二叉樹而言,時間複雜度由T(n)=i=0h1n2i=O(n)T(n)=\sum_{i=0}^{h-1}\frac{n}{2^i}=O(n)給出。最差的情況是二叉樹退化成鏈表,則需要O(n2)O(n^2)的時間。

法2:我們考慮每個節點應該要加到res的哪一層裏,容易發現,一個節點應該加在res的哪個位置與其到其左右子樹最深的葉子有多少步有關(稱爲這個節點的高度)。所以我們可以在遞歸回溯的時候算得這個節點的深度,然後按照深度加到res的對應位置的列表上。這樣就避免了法1裏的頻繁DFS導致節點被重複搜索的問題(實際上就是後序遍歷)。代碼如下:

import java.util.ArrayList;
import java.util.List;

public class Solution {
    public List<List<Integer>> findLeaves(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        dfs(root, res);
        return res;
    }
    
    private int dfs(TreeNode root, List<List<Integer>> res) {
        // 葉子的高度是0,所以規定走到null就返回-1
        if (root == null) {
            return -1;
        }
        
        // 得到root的高度
        int height = 1 + Math.max(dfs(root.left, res), dfs(root.right, res));
        // 如果這個高度對應的位置沒有list,就new一個出來,並把root的值加進去
        if (height >= res.size()) {
            res.add(new ArrayList<>());
        }
        res.get(height).add(root.val);
        return height;
    }
}

時間複雜度O(n)O(n),空間O(h)O(h)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章