Leetcode145 二叉樹的後序遍歷[Hard] -JAVA

題目傳送門

Leetcode145 二叉樹的後序遍歷[Hard] -JAVA

題目

給定一個二叉樹,返回它的 後序 遍歷。

示例:

輸入: [1,null,2,3]

 1
  \
   2
  /
 3

輸出: [3,2,1]

進階: 遞歸算法很簡單,你可以通過迭代算法完成嗎?
Related Topics 棧 樹

思路

後序遍歷:左-右-中
題目也說了遞歸很簡單,使用一個DFS(深度優先遍歷),分別按左右中,加到結果列表裏。我相信你也可以寫得出來。

什麼是迭代?
遞歸是使用函數棧去實現的,也就是自己調用自己。每次調用都需要去開闢方法棧空間,當棧太深時就會出現棧溢出。
那麼如何用迭代實現呢?
概念 —— 迭代是重複反饋過程的活動,其目的通常是爲了接近併到達所需的目標或結果。 每一次對過程的重複被稱爲一次迭代,而每一次迭代得到的結果會被用來作爲下一次迭代的初始值。
說白了,就是能用forwhile實現的,就別用遞歸。
一般的能寫成遞歸的都能轉化成迭代,但迭代寫完後相對於遞歸來說沒有那麼好理解

解法

遞歸

class Solution {
    List<Integer> res ;
    public List<Integer> postorderTraversal(TreeNode root) {
        res = new ArrayList<>();
        dfs(root);
        return res;
    }

    public void dfs(TreeNode node) {
        if (node == null) return ;
        dfs(node.left);
        dfs(node.right);
        res.add(node.val);
    }
}

迭代

        1
       /  \
      2    3
     / \  / \
    4   5 6  7

以上面這棵樹爲例子,我們要實現按照左邊-右邊-中間的順序輸出。在這裏用棧就很巧妙,每次都推出一個元素,並將左右子樹分別壓入棧。而推出的這個元素就是根節點,每次拼接到鏈表的頭部。
結合代碼走一遍
1做爲根節點,壓入棧。
推出1,將自己的左右節點23入棧。(按2,3 的順序入棧)
推出3,將自己的左右節點67入棧。
推出77爲葉子節點,無入棧元素
推出66爲葉子節點,無入棧元素
此時右子樹已經遍歷完。
推出2,將自己的左右節點45入棧。(按4,5 的順序入棧)
推出55爲葉子節點,無入棧元素
推出44爲葉子節點,無入棧元素
完成!棧裏已無元素。
這裏呢畫個圖就能一下子明白啥回事!

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        LinkedList<Integer> res = new LinkedList<>();
        if (root==null) return res;
        
        Stack<TreeNode> stack = new Stack<>(); 
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode pop = stack.pop();
            res.addFirst(pop.val); 
            if (null!=pop.left) stack.push(pop.left);
            if (null!=pop.right) stack.push(pop.right);
        }
        return res;
    }

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