144. 二叉樹的前序遍歷(java實現)--LeetCode

一碗機智的糖漿發表於2020-12-27

題目:

給你二叉樹的根節點 root ,返回它節點值的 前序 遍歷。

示例 1:
在這裡插入圖片描述

輸入:root = [1,null,2,3]
輸出:[1,2,3]

示例 2:

輸入:root = []
輸出:[]

示例 3:

輸入:root = [1]
輸出:[1]

示例 4:
在這裡插入圖片描述

輸入:root = [1,2]
輸出:[1,2]

示例 5:
在這裡插入圖片描述

輸入:root = [1,null,2]
輸出:[1,2]

提示:

  • 樹中節點數目在範圍 [0, 100] 內
  • -100 <= Node.val <= 100

進階:遞迴演算法很簡單,你可以通過迭代演算法完成嗎?

解法1:遞迴

   	class TreeNode{
        int val;
        TreeNode left,right;
        public TreeNode(int val){
            this.val=val;
        }
        public TreeNode(TreeNode left,TreeNode right,int val){
            this.left=left;
            this.right=right;
            this.val=val;
        }
    }

    public List<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<>();
        recursive(root,result);
        return result;
    }

    private void recursive(TreeNode root, ArrayList<Integer> result) {
        if (root==null)return;
        result.add(root.val);
        recursive(root.left,result);
        recursive(root.right,result);
    }

時間複雜度:On

空間複雜度:On
在這裡插入圖片描述

解法2:棧

/**
 * 思路:
 * stack
 * 核心思路:
 * 窮舉完左邊所有節點,窮舉的過程中新增根節點的值到result。
 * 在走右邊節點,同樣的套路窮舉左邊
 *
 * 把根節點放入棧,並在result中存放。
 * 之後迴圈的走根節點的左節點,之後不斷的在棧中加入根節點,結果集中加入他的值,並把左節點賦值給root。
 * 走完左的所有情況後,出棧根節點,走根的右節點,迴圈這個過程
 */
    class TreeNode{
        int val;
        TreeNode left,right;
        public TreeNode(int val){
            this.val=val;
        }
        public TreeNode(TreeNode left,TreeNode right,int val){
            this.left=left;
            this.right=right;
            this.val=val;
        }
    }

    public List<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<>();
        ArrayDeque<TreeNode> stack = new ArrayDeque<>();
        while (!stack.isEmpty()||root!=null){
            while (root!=null){
                stack.push(root);
                result.add(root.val);
                root=root.left;
            }
            root=stack.pop().right;
        }
        return result;
    }

時間複雜度:On

空間複雜度:On
在這裡插入圖片描述

解法3:Morris

/**
 * 思路:
 * 莫里斯
 * 核心思路:
 * 把樹按照前序遍歷轉換為連結串列
 *
 * root節點按照前序遍歷的順序移動
 * 找到當前節點的左節點最右的節點tail
 * 如果tail的右指標是null,讓這個節點的右指標指向當前節點。結果集中加入當前節點,並且移動當前節點root到left
 * 如果tail的右指標不是null,說明左邊都遍歷完了,root指向右邊,遍歷右邊。
 * 左邊遍歷完,把當前節點加入到結果集,root指向右邊,遍歷右邊。
 */
   	class TreeNode{
        int val;
        TreeNode left,right;
        public TreeNode(int val){
            this.val=val;
        }
        public TreeNode(TreeNode left,TreeNode right,int val){
            this.left=left;
            this.right=right;
            this.val=val;
        }
    }
     public List<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<>();
        while (root!=null){
            if (root.left!=null){
                TreeNode tail = root.left;
                while (tail.right!=null&&tail.right!=root)tail=tail.right;
                if (tail.right==null){
                    result.add(root.val);
                    tail.right=root;
                    root=root.left;
                }else {
                    root=root.right;
                }
            }else {
                result.add(root.val);
                root=root.right;
            }
        }
        return result;
    }

時間複雜度:On

空間複雜度:On
在這裡插入圖片描述

解法4:顏色標記

/**
 * 思路:
 * 顏色標記
 * 建立棧,棧中存放Pair物件,key是顏色0代表沒有遍歷,1代表已經遍歷,value是節點
 * 判斷是否顏色:
 * 0:按照右左根的順序加入到棧中,根要標記1
 * 1:加入到結果集
 */
    class TreeNode{
        int val;
        TreeNode left;
        TreeNode right;
        public TreeNode(int data){
            this.val=data;
        }
    }
    
    public List<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<>();
        if (root==null)return result;
        ArrayDeque<Pair<Integer, TreeNode>> stack = new ArrayDeque<>();
        stack.push(new Pair<>(0,root));
        while (!stack.isEmpty()){
            Pair<Integer, TreeNode> pop = stack.pop();
            if (pop.getKey()==0){
                if (pop.getValue().right!=null)stack.push(new Pair<>(0,pop.getValue().right));
                if (pop.getValue().left!=null)stack.push(new Pair<>(0,pop.getValue().left));
                stack.push(new Pair<>(1,pop.getValue()));
            }else {
                result.add(pop.getValue().val);
            }
        }
        return result;
    }

時間複雜度:On

空間複雜度:On
在這裡插入圖片描述

相關文章