文章目录
- [144. 二叉树的前序遍历](https://leetcode-cn.com/problems/binary-tree-preorder-traversal/)
- 思路
- [589. N叉树的前序遍历](https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal/)
- 思路
- [94. 二叉树的中序遍历](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/)
- 思路
- [145. 二叉树的后序遍历](https://leetcode-cn.com/problems/binary-tree-postorder-traversal/)
- 思路
- [590. N叉树的后序遍历](https://leetcode-cn.com/problems/n-ary-tree-postorder-traversal/)
- 思路
- [102. 二叉树的层次遍历](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/)
- 思路
- [107. 二叉树的层次遍历 II](https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/)
- 思路
144. 二叉树的前序遍历
/**
* Definition for a binary tree node.
* public class TreeNode(var `val`: Int) {
* var left: TreeNode? = null
* var right: TreeNode? = null
* }
*/
import java.util.*
class Solution {
fun preorderTraversal(root: TreeNode?): List<Int> {
val result = ArrayList<Int>()
val stack = Stack<TreeNode?>()
stack.push(root)
while (!stack.isEmpty()) {
val node = stack.pop() ?: continue
result.add(node.`val`)
stack.push(node.right)
stack.push(node.left)
}
return result
}
}
思路
采用栈保存需要前序遍历的结点。每次pop一个结点,记录其val值后,将其子节点倒序压入栈中。
递归实现比较简单:
/**
* Definition for a binary tree node.
* public class TreeNode(var `val`: Int) {
* var left: TreeNode? = null
* var right: TreeNode? = null
* }
*/
class Solution {
private val result = ArrayList<Int>()
fun preorderTraversal(root: TreeNode?): List<Int> {
pre(root)
return result
}
private fun pre(root: TreeNode?) {
if (root == null) return
result.add(root.`val`)
pre(root.left)
pre(root.right)
}
}
589. N叉树的前序遍历
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val,List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<Integer> preorder(Node root) {
List<Integer> result = new ArrayList<>();
Stack<Node> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
Node node = stack.pop();
if (node == null) continue;
result.add(node.val);
for (Node child : reverse(node.children)) {
stack.push(child);
}
}
return result;
}
private List<Node> reverse(List<Node> nodes) {
List<Node> result = new ArrayList<>();
for (int i = 0; i < nodes.size(); i++) {
result.add(nodes.get(nodes.size() - i - 1));
}
return result;
}
}
思路
采用栈保存需要前序遍历的结点。每次pop一个结点,记录其val值后,将其子节点倒序压入栈中。
递归实现比较简单:
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val,List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
private List<Integer> result = new ArrayList<>();
public List<Integer> preorder(Node root) {
pre(root);
return result;
}
private void pre(Node root) {
if (root == null) return;
result.add(root.val);
for (Node child : root.children) {
pre(child);
}
}
}
94. 二叉树的中序遍历
/**
* Example:
* var ti = TreeNode(5)
* var v = ti.`val`
* Definition for a binary tree node.
* class TreeNode(var `val`: Int) {
* var left: TreeNode? = null
* var right: TreeNode? = null
* }
*/
import java.util.*
class Solution {
private val result = mutableListOf<Int>()
fun inorderTraversal(root: TreeNode?): List<Int> {
root ?: return listOf()
val stack = Stack<TreeNode?>().apply {
push(root)
}
result.clear()
inorderStack(stack)
return result.toList()
}
fun inorderStack(stack: Stack<TreeNode?>) {
while (true) {
var node = stack.last()
if (node != null) {
stack.push(node.left)
} else {
// 弹出这个空结点
stack.pop()
if (stack.isEmpty()) break
// 弹出栈顶的结点
node = stack.pop() ?: continue
result.add(node.`val`)
stack.push(node.right)
}
}
}
}
思路
栈保存应该遍历的结点顺序。如果一个结点不为空,将其左结点压入栈中,直到左结点压完后,弹出栈顶的结点,记录其值后,压入其右结点。
递归实现比较简单:
/**
* Example:
* var ti = TreeNode(5)
* var v = ti.`val`
* Definition for a binary tree node.
* class TreeNode(var `val`: Int) {
* var left: TreeNode? = null
* var right: TreeNode? = null
* }
*/
class Solution {
private val result = mutableListOf<Int>()
fun inorderTraversal(root: TreeNode?): List<Int> {
inorder(root)
return result.toList()
}
private fun inorder(node: TreeNode?) {
node ?: return
inorder(node.left)
result.add(node.`val`)
inorder(node.right)
}
}
145. 二叉树的后序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
import java.util.*
class Solution {
private val result = mutableListOf<Int>()
fun postorderTraversal(root: TreeNode?): List<Int> {
root ?: return listOf()
val stack = Stack<TreeNode?>()
stack.push(root)
result.clear()
postorder(stack)
return result.toList()
}
private fun postorder(stack: Stack<TreeNode?>) {
while (!stack.isEmpty()) {
val node = stack.pop() ?: return
result.add(node.`val`)
if (node.left != null) stack.push(node.left)
if (node.right != null) stack.push(node.right)
}
result.reverse()
}
}
思路
采用根右左的方式遍历树,然后将结果反转。
思路二:记录上一个访问的结点。如果是当前结点的子结点,说明其左右结点均已访问,将当前结点出栈。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
import java.util.*
class Solution {
private val result = mutableListOf<Int>()
fun postorderTraversal(root: TreeNode?): List<Int> {
root ?: return listOf()
val stack = Stack<TreeNode?>()
stack.push(root)
result.clear()
postorder(stack)
return result.toList()
}
private fun postorder(stack: Stack<TreeNode?>) {
var last: TreeNode? = null
while (true) {
val node = stack.last() ?: return
if ((node.left == null && node.right == null) || (last != null && (last == node.left || last == node.right))) {
result.add(node.`val`)
last = node
stack.pop()
if (stack.isEmpty()) break
} else {
if (node.right != null) stack.push(node.right)
if (node.left != null) stack.push(node.left)
}
}
}
}
思路三:递归实现,比较简单。
/**
* Example:
* var ti = TreeNode(5)
* var v = ti.`val`
* Definition for a binary tree node.
* class TreeNode(var `val`: Int) {
* var left: TreeNode? = null
* var right: TreeNode? = null
* }
*/
class Solution {
private val result = mutableListOf<Int>()
fun postorderTraversal(root: TreeNode?): List<Int> {
postorder(root)
return result.toList()
}
private fun postorder(node: TreeNode?) {
node ?: return
postorder(node.left)
postorder(node.right)
result.add(node.`val`)
}
}
590. N叉树的后序遍历
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val,List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<Integer> postorder(Node root) {
Stack<Node> stack = new Stack<>();
stack.push(root);
return postorderStack(stack);
}
private List<Integer> postorderStack(Stack<Node> stack) {
List<Integer> result = new ArrayList<>();
while (!stack.isEmpty()) {
Node node = stack.pop();
if (node == null) continue;
result.add(node.val);
for (Node child : node.children) {
stack.push(child);
}
}
return reverse(result);
}
private List<Integer> reverse(List<Integer> integers) {
List<Integer> result = new ArrayList<>();
for (int i = 0; i < integers.size(); i++) {
result.add(integers.get(integers.size() - i - 1));
}
return result;
}
}
思路
与二叉树的后序遍历类似,采用根右左的方式遍历树,然后将结果反转。
102. 二叉树的层次遍历
/**
* Example:
* var ti = TreeNode(5)
* var v = ti.`val`
* Definition for a binary tree node.
* class TreeNode(var `val`: Int) {
* var left: TreeNode? = null
* var right: TreeNode? = null
* }
*/
class Solution {
fun levelOrder(root: TreeNode?): List<List<Int>> {
val result = mutableListOf<List<Int>>()
var current = mutableListOf<TreeNode?>()
current.add(root)
while (!current.isEmpty()) {
val children = mutableListOf<TreeNode?>()
val list = mutableListOf<Int>()
for (node in current) {
node ?: continue
list.add(node.`val`)
children.add(node.left)
children.add(node.right)
}
if (!list.isEmpty()) result.add(list.toList())
current = children
}
return result
}
}
思路
记录当前层级的结点,依次取值保存到list中,当前层级遍历完成后,将其计入result数组。
然后记录当前层级的子节点,迭代求list,直至整个遍历完成。
107. 二叉树的层次遍历 II
/**
* Example:
* var ti = TreeNode(5)
* var v = ti.`val`
* Definition for a binary tree node.
* class TreeNode(var `val`: Int) {
* var left: TreeNode? = null
* var right: TreeNode? = null
* }
*/
class Solution {
fun levelOrderBottom(root: TreeNode?): List<List<Int>> {
val result = mutableListOf<List<Int>>()
var current = mutableListOf<TreeNode?>()
current.add(root)
while (!current.isEmpty()) {
val children = mutableListOf<TreeNode?>()
val list = mutableListOf<Int>()
for (node in current) {
node ?: continue
list.add(node.`val`)
children.add(node.left)
children.add(node.right)
}
if (!list.isEmpty()) result.add(list.toList())
current = children
}
return result.reversed()
}
}
思路
记录当前层级的结点,依次取值保存到list中,当前层级遍历完成后,将其计入result数组。
然后记录当前层级的子节点,迭代求list,直至整个遍历完成后,翻转结果即可。