[lintcode] Binary Tree Preorder Traversal
2015-10-06 10:45
295 查看
Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes' values.
Example
Given binary tree
return
SOLUTION 1:
这题首先应该想到递归做法,最简单直观的也是递归做法。首先先来说一下递归是什么,递归其实就是自己调用自己,但是注意的是,递归往往没有返回值。
在用递归方法的时候要定义清楚,递归方法接收了什么参数,做了什么事情,在这个题里面,看到返回值是个ArrayList,那么首先应该new一个存放结果的ArrayList并且用于最后返回,
所以说递归函数一定会接受一个ArrayList,而且一定会有一个根结点,所以这个递归函数应该是这样的:traversal(TreeNode root, ArrayList<Integer> result){},然后定义这个函数做了什么事情,就是把以root为根的前序遍历加到result里面。
时间复杂度分析:每个点只操作一次,一次操作都是O(1)的,所以总的时间复杂度就是O(N),其中N是二叉树中点的个数。
后面就很简单的看一下代码了:
SOLUTION 2:
第二种方法,就是几乎使用所有二叉树的分治法,分治法其实也是一种递归方法,不过相当于把给的参数分成两部分,分别处理,在二叉树这种结构中,天然的把自己分成了两个部分,可以直接使用分治法。
注意的是分治法一般都是有返回值的,这个跟一般的递归方法是不一样的。
时间复杂度分析:Divide部分,时间复杂度还是O(N),因为每个点还是只遍历一次;但是在Conquer里面,用数组result.add这个操作的时间复杂度太费了,可能是O(N),总的时间复杂度可能就退化成了O(N^2)了,当然也可以用链表优化,这样conquer的操作就也是O(1)的了。
代码如下:
SOLUTION 3:
比较重要的是第三种方法,这种方法是非递归方法。
对于递归方法,它的一个坏处就是会stack overflow,就是栈溢出,这个是由于当运行一个程序的时候,系统会自动分配给这个程序一块栈内存,8MB,也就是说,递归过深的时候,就会消耗大量栈空间,当其超过8MB时候就会栈溢出,所以,往往能用非递归就不用递归,除非非递归太复杂了。
非递归的解体方法就是用栈(stack)模拟递归。具体方法见代码:
Given a binary tree, return the preorder traversal of its nodes' values.
Example
Given binary tree
{1,#,2,3}:
1 \ 2 / 3
return
[1,2,3].
SOLUTION 1:
这题首先应该想到递归做法,最简单直观的也是递归做法。首先先来说一下递归是什么,递归其实就是自己调用自己,但是注意的是,递归往往没有返回值。
在用递归方法的时候要定义清楚,递归方法接收了什么参数,做了什么事情,在这个题里面,看到返回值是个ArrayList,那么首先应该new一个存放结果的ArrayList并且用于最后返回,
所以说递归函数一定会接受一个ArrayList,而且一定会有一个根结点,所以这个递归函数应该是这样的:traversal(TreeNode root, ArrayList<Integer> result){},然后定义这个函数做了什么事情,就是把以root为根的前序遍历加到result里面。
时间复杂度分析:每个点只操作一次,一次操作都是O(1)的,所以总的时间复杂度就是O(N),其中N是二叉树中点的个数。
后面就很简单的看一下代码了:
public class Solution { /** * @param root: The root of binary tree. * @return: Preorder in ArrayList which contains node values. */ public ArrayList<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> result = new ArrayList<Integer>(); if (root == null){ return result; } traversal(root, result); return result; } private void traversal(TreeNode root, ArrayList<Integer> result){ if (root == null){ return; } result.add(root.val); traversal(root.left, result); traversal(root.right, result); } }
SOLUTION 2:
第二种方法,就是几乎使用所有二叉树的分治法,分治法其实也是一种递归方法,不过相当于把给的参数分成两部分,分别处理,在二叉树这种结构中,天然的把自己分成了两个部分,可以直接使用分治法。
注意的是分治法一般都是有返回值的,这个跟一般的递归方法是不一样的。
时间复杂度分析:Divide部分,时间复杂度还是O(N),因为每个点还是只遍历一次;但是在Conquer里面,用数组result.add这个操作的时间复杂度太费了,可能是O(N),总的时间复杂度可能就退化成了O(N^2)了,当然也可以用链表优化,这样conquer的操作就也是O(1)的了。
代码如下:
public class Solution { /** * @param root: The root of binary tree. * @return: Preorder in ArrayList which contains node values. */ public ArrayList<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> result = new ArrayList<Integer>(); if (root == null){ return result; } // 左右两边分别递归处理===》分治法之“分” ArrayList<Integer> left = preorderTraversal(root.left); ArrayList<Integer> right = preorderTraversal(root.right); // 左右两边再跟根结点合并 result.add(root.val); result.addAll(left); result.addAll(right); return result; } }
SOLUTION 3:
比较重要的是第三种方法,这种方法是非递归方法。
对于递归方法,它的一个坏处就是会stack overflow,就是栈溢出,这个是由于当运行一个程序的时候,系统会自动分配给这个程序一块栈内存,8MB,也就是说,递归过深的时候,就会消耗大量栈空间,当其超过8MB时候就会栈溢出,所以,往往能用非递归就不用递归,除非非递归太复杂了。
非递归的解体方法就是用栈(stack)模拟递归。具体方法见代码:
public class Solution { /** * @param root: The root of binary tree. * @return: Preorder in ArrayList which contains node values. */ public ArrayList<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> result = new ArrayList<Integer>(); if (root == null){ return result; } Stack<TreeNode> stack = new Stack<TreeNode>(); stack.push(root); while (!stack.empty()){ TreeNode temp = stack.pop(); result.add(temp.val); // 由于stack是先进后出,所以压栈时候要先压入right子树 // 这样才能保证出栈时候是左先出,右后出 if (temp.right != null){ stack.push(temp.right); } if (temp.left != null){ stack.push(temp.left); } } return result; } }
相关文章推荐
- 排序之插入排序
- Spring标签:context:component-scan
- Python笔记--lambda
- [转]PHP经验——PHPDoc PHP注释的标准文档
- 第三次作业:0~10的随机四则运算
- HDU 3374 String Problem(最小表示法·KMP)
- (日志,《算法导论》.6.4)优先队列,堆,代码
- Erasing Edges - SGU 136(构造多边形)
- sap用户出口 badi查询程序(通过事务代码)
- java使用JDBC连接MYSQL数据库
- openerp wizard to tree view
- Java集合学习
- 随机产生13个0~51不同的随机数 -思想(定义参考系)
- C语言-八皇后问题
- Java破解简单验证码
- std::auto_ptr boost::shared_ptr智能指针的应用
- leetcode 263&264: Ugly Number I & II
- Win10预览版10558:Edge浏览器加入标签页预览
- Hibernate QBC查询
- HDU 5072 Coprime [数学]