zoukankan      html  css  js  c++  java
  • 144. Binary Tree Preorder Traversal

    题目:

    Given a binary tree, return the preorder traversal of its nodes' values.

    For example:
    Given binary tree {1,#,2,3},

       1
        
         2
        /
       3
    

    return [1,2,3].

    Note: Recursive solution is trivial, could you do it iteratively?

    Hide Tags
     Tree Stack
     

    连接: http://leetcode.com/problems/binary-tree-preorder-traversal/

    题解:

    二叉树先序遍历, root -> left -> right。使用一个栈来维护已经访问过的节点。当root不为空时,当前节点入栈,输出节点值,继续向左子树遍历。当root为空,从栈中弹出节点,向右子树进行遍历。

    Iterative:

    Time Complexity - O(n),  Space Complexity - O(n)。

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

    Recursive:

    Time Complexity - O(n), Space Complexity - O(n)。

    public class Solution {
        public ArrayList<Integer> preorderTraversal(TreeNode root) {
            ArrayList<Integer> result = new ArrayList<Integer>();
            if(root == null)
                return result;
            helper(result, root);
            return result;
        }
        
        private void helper(ArrayList<Integer> result, TreeNode root){
            if(root == null)
                return;
            result.add(root.val);
            helper(result, root.left);
            helper(result, root.right);
        }
    }

    Update:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            if(root == null)
                return res;
            Stack<TreeNode> stack = new Stack<>();
            stack.push(root);
            
            while(!stack.isEmpty()) {
                root = stack.pop();
                if(root != null) {
                    res.add(root.val);
                    if(root.right != null)
                        stack.push(root.right);
                    if(root.left != null)
                        stack.push(root.left);
                }
            }
            
            return res;
        }
    }

    Morris-Travel: 待定。

    二刷:

    Java:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            if (root == null) {
                return res;
            }
            Stack<TreeNode> stack = new Stack<>();
            while (root != null || !stack.isEmpty()) {
                if (root != null) {
                    res.add(root.val);
                    stack.push(root.right);
                    root = root.left;
                } else {
                    root = stack.pop();
                }
            }
            return res;
        }
    }

    三刷:

    Java:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            Stack<TreeNode> stack = new Stack<>();
            
            while (!stack.isEmpty() || root != null) {
                if (root != null) {
                    res.add(root.val);
                    stack.push(root.right);
                    root = root.left;
                } else {
                    root = stack.pop();
                }
            }
            return res;
        }
    }

    Recursive:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            preorderTraversal(res, root);
            return res;
        }
        
        private void preorderTraversal(List<Integer> res, TreeNode root) {
            if (root == null) return;
            res.add(root.val);
            preorderTraversal(res, root.left);
            preorderTraversal(res, root.right);
        }
    }

    三刷:

    Java:

    Iterative with a stack:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            TreeNode node = root;
            Stack<TreeNode> stack = new Stack<>();
            while (node != null || !stack.isEmpty()) {
                if (node != null) {
                    res.add(node.val);
                    stack.push(node);
                    node = node.left;
                } else {
                    node = stack.pop();
                    node = node.right;
                }
            }
            return res;
        }
    }

    Recursive:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            preorderTraversal(res, root);
            return res;
        }
        
        private void preorderTraversal(List<Integer> res, TreeNode root) {
            if (root == null) return;
            res.add(root.val);
            preorderTraversal(res, root.left);
            preorderTraversal(res, root.right);
        }
    }

    Morris traversal:

    使用了类似in-order Morris Traversal类似的代码。在可以改变树结构的情况下,使用空的右子树来连接到父节点,最后再还原树结构。下面详述一下步骤:

    1. 在当前node非空的情况下对树进行遍历。仍然是先判断左子树是否为空,假如为空,则我们将当前节点node.val加入到结果集里,继续向右遍历树
    2. 否则左子树非空,这时我们向左子树里查找当前节点node的predecessor,简称prev,即左子树中最右端的元素。依然是两种情况:
      1. 当prev.right为空时,我们第一次访问此节点,这时把prev.right设置为当前节点node,然后把当前节点node.val加入到结果集里,向左遍历树
      2. 否则prev.right = 为当前node,说明我们是第二次访问这个节点,这时要做一个树的还原操作,也就是断开prev和node的连接,即prev.right = null,然后向右遍历树。这时候因为我们的当前节点node已经被处理过了,所以不要再次处理node.val 
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            TreeNode node = root, prev = null;
            while (node != null) {
                if (node.left == null) {
                    res.add(node.val);
                    node = node.right;
                } else {
                    prev = node.left;
                    while (prev.right != null && prev.right != node) {
                        prev = prev.right;
                    }
                    if (prev.right == null) {
                        prev.right = node;
                        res.add(node.val);
                        node = node.left;
                    } else {
                        prev.right = null;
                        node = node.right;
                    }
                }
            }
            return res;
        }
    }

    Update:

    简化了一下,反而比较古怪,不易理解。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            TreeNode node = root, prev = null;
            while (node != null) {
                prev = node.left;
                while (prev != null && prev.right != null && prev.right != node) {
                    prev = prev.right;
                }
                if (prev != null && prev.right == null) {
                    prev.right = node;
                    res.add(node.val);
                    node = node.left;
                } else {
                    if (prev != null) prev.right = null;
                    else res.add(node.val);
                    node = node.right;
                }    
            }
            return res;
        }
    }

    Reference:

    https://leetcode.com/discuss/9734/accepted-code-explaination-with-algo

    https://leetcode.com/discuss/5331/whats-the-simplest-and-cleanest-answer

    https://leetcode.com/discuss/23326/very-simple-iterative-python-solution

    https://leetcode.com/discuss/19798/accepted-iterative-solution-in-java-using-stack

    https://leetcode.com/discuss/32904/3-different-solutions

    https://leetcode.com/discuss/49926/easy-read-java-solutions-for-both-iterative-recursive-300ms

    https://leetcode.com/discuss/46894/java-solution-both-recursion-and-iteration 

    94. Binary Tree Inorder Traversal

  • 相关阅读:
    装饰器模式
    原型模式
    观察者模式
    Apollo 代码的编译演示
    Apollo 框架的剖析1
    gPRC学习笔记
    Docker入门
    ROS入门学习
    Mudo C++网络库第十一章学习笔记
    Mudo C++网络库第十章学习笔记
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4483758.html
Copyright © 2011-2022 走看看