????前言
???? 算法题 ????
???? 每天打卡一道算法题,既是一个学习过程,又是一个分享的过程????
???? 提示:本专栏解题 编程语言一律使用 C# 和 Java 两种进行解题
???? 要保持一个每天都在学习的状态,让我们一起努力成为算法大神吧????!
???? 今天是力扣算法题持续打卡第39天????!
???? 算法题 ????
????原题样例:二叉树的前序遍历
给你二叉树的根节点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
????C#方法:递归
思路解析
快慢指针,快慢指针同时从头节点出发,快指针每次走两步,慢指针每次走一步,如果存在环的话,快指针迟早赶上慢指针。
代码:
public class Solution { private IList<int> res = new List<int>(); public IList<int> PreorderTraversal(TreeNode root) { Traversal(root); return res; } private void Traversal(TreeNode node) { if(node!=null) { res.Add(node.val); PreorderTraversal(node.left); PreorderTraversal(node.right); } } }
执行结果
通过 执行用时:224 ms,在所有 C# 提交中击败了70.79%的用户 内存消耗:29.8 MB,在所有 C# 提交中击败了79.47%的用户
????Java 方法一:递归
思路解析
首先我们需要了解什么是二叉树的前序遍历:按照访问根节点——左子树——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。
因此整个遍历过程天然具有递归的性质,我们可以直接用递归函数来模拟这一过程。
定义preorder(root)表示当前遍历到 root节点的答案。按照定义,我们只要首先将root 节点的值加入答案,然后递归调用 preorder(root.left)来遍历root节点的左子树,最后递归调用preorder(root.right)来遍历 root节点的右子树即可,递归终止的条件为碰到空节点。
代码:
class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<Integer>(); preorder(root, res); return res; } public void preorder(TreeNode root, List<Integer> res) { if (root == null) { return; } res.add(root.val); preorder(root.left, res); preorder(root.right, res); } }
执行结果
通过 执行用时:0 ms,在所有 Java 提交中击败了100.00%的用户 内存消耗:36.6 MB,在所有 Java 提交中击败了59.89%的用户 • 1 • 2 • 3
复杂度分析
时间复杂度:O( n ),其中 n 是二叉树的节点数 空间复杂度:O( n )
????Java 方法一:迭代
思路解析
我们也可以用迭代的方式实现方法一的递归函数,两种方式是等价的,区别在于递归的时候隐式地维护了一个栈,
而我们在迭代的时候需要显式地将这个栈模拟出来,其余的实现与细节都相同,具体可以参考下面的代码
代码:
class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<Integer>(); if (root == null) { return res; } Deque<TreeNode> stack = new LinkedList<TreeNode>(); TreeNode node = root; while (!stack.isEmpty() || node != null) { while (node != null) { res.add(node.val); stack.push(node); node = node.left; } node = stack.pop(); node = node.right; } return res; } }
执行结果
通过 执行用时:0 ms,在所有 Java 提交中击败了100.00%的用户 内存消耗:36.9 MB,在所有 Java 提交中击败了5.45%的用户
复杂度分析
时间复杂度:O( n ),其中 n 是二叉树的节点数 空间复杂度:O( n ) • 1 • 2
????总结
- 今天是力扣算法题打卡的第三十九天!
- 文章采用
C#
和Java
两种编程语言进行解题 - 一些方法也是参考力扣大神写的,也是边学习边分享,再次感谢算法大佬们