提前要了解二叉树的分类 二叉树的两种存储方式 二叉树的两大种遍历方式以及深度遍历中的三种遍历方式 常常与dfs bfs混合使用
本文只介绍二叉树相关的leetcode习题 对基础的语法知识点不做过多赘述
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<Integer> ans = new ArrayList<>();
public List<Integer> preorderTraversal(TreeNode root) {
dfs(root);
return ans;
}
public void dfs(TreeNode root){
if(root == null) return;
ans.add(root.val);
dfs(root.left);
dfs(root.right);
}
}
class Solution {
List<Integer> ans = new ArrayList<>();
Stack<TreeNode> st = new Stack<>();
public List<Integer> preorderTraversal(TreeNode root) {
TreeNode cur = root;
while(cur != null || !st.isEmpty()){
while(cur != null){
ans.add(cur.val);
st.push(cur);
cur = cur.left;
}
cur = st.pop();
cur = cur.right;
}
return ans;
}
}
先遍历根右左 然后翻转过来
class Solution {
List<Integer> ans = new ArrayList<>();
Stack<TreeNode> st = new Stack<>();
public List<Integer> postorderTraversal(TreeNode root) {
TreeNode cur = root;
while(cur != null || !st.isEmpty()){
while(cur != null){
ans.add(cur.val);
st.push(cur);
cur = cur.right;
}
cur = st.pop();
cur = cur.left;
}
Collections.reverse(ans);
return ans;
}
}
建立一个上一个节点
class Solution {
List<Integer> ans = new ArrayList<>();
Stack<TreeNode> st = new Stack<>();
public List<Integer> postorderTraversal(TreeNode root) {
TreeNode cur = root;
TreeNode pre = null;
while(cur != null || !st.isEmpty()){
while(cur != null){
st.push(cur);
cur = cur.left;
}
cur = st.peek();
//右边表示没遍历上一个节点
if(cur.right != null && cur.right != pre){
cur = cur.right;
}else{
st.pop();
ans.add(cur.val);
pre = cur;
cur = null;
}
}
return ans;
}
}
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
输入: [1,2,3,null,5,null,4]
输出: [1,3,4]
层序遍历的模板 在每一层中把该层中最后一个元素放入队列中即可
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> ans = new ArrayList<>();
if(root == null) return ans;
Queue<TreeNode> q = new LinkedList<TreeNode>();
q.add(root);
while(!q.isEmpty()){
int len = q.size();
for(int i = 0 ; i < len ; i++){
TreeNode t = q.poll();
if(t.left != null) q.add(t.left);
if(t.right != null) q.add(t.right);
if(i == len-1) ans.add(t.val);
}
}
return ans;
}
}
给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。
输入:root = [3,9,20,null,null,15,7]
输出:[3.00000,14.50000,11.00000]
解释:第 0 层的平均值为 3,第 1 层的平均值为 14.5,第 2 层的平均值为 11 。
因此返回 [3, 14.5, 11] 。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> ans = new ArrayList<>();
Queue<TreeNode> q = new LinkedList<>();
if(root == null) return ans;
q.add(root);
while(!q.isEmpty()){
int len = q.size();
double sum = 0 ;
for(int i = 0 ; i < len ; i ++){
TreeNode t = q.poll();
sum += t.val;
if(t.left != null) q.add(t.left);
if(t.right != null) q.add(t.right);
}
ans.add(sum/len);
}
return ans;
}
}
给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
输入:root = [1,null,3,2,4,null,5,6]
输出:[[1],[3,2,4],[5,6]]
/*
// Definition for a Node.
class Node {
public int val;
public List children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> ans = new ArrayList<>();
Queue<Node> q = new LinkedList<>();
if(root == null) return ans;
q.add(root);
while(!q.isEmpty()){
List<Integer> res = new ArrayList<>();
int len = q.size();
for(int i = 0 ; i < len ; i ++){
Node t = q.poll();
res.add(t.val);
for(Node c : t.children) q.add(c);
}
ans.add(res);
}
return ans ;
}
}
给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
输入: root = [1,3,2,5,3,null,9]
输出: [1,3,9]
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> largestValues(TreeNode root) {
List<Integer> ans = new ArrayList<>();
Queue<TreeNode> q = new LinkedList<>();
if(root == null) return ans;
q.add(root);
while(!q.isEmpty()){
int len = q.size();
int m = Integer.MIN_VALUE ;
for(int i = 0 ; i < len ; i++){
TreeNode t = q.poll();
m = Math.max(m,t.val);
if(t.left != null) q.add(t.left);
if(t.right != null) q.add(t.right);
}
ans.add(m);
}
return ans;
}
}
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
TreeNode t = root.left;
root.left = root.right;
root.right = t ;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
输入:root = [1,2,3,4,5,6]
输出:6
用二分的思想 O(log^2 n)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int countNodes(TreeNode root) {
if(root == null) return 0 ;
int x = 1 , y = 1 ;
TreeNode l = root.left ;
TreeNode r = root.right ;
while(l != null){//如果是root 的话 那么x y 初始化要是0
l = l.left ;
x++;
}
while(r != null){
r = r.right;
y++;
}
//二者相同为满二叉树 2^x -1
if(x == y) return (1 << x) -1;
//递归到左边算加上根节点 在递归到右边算
return countNodes(root.left) + 1 + countNodes(root.right);
}
}
给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
输入:root = [1,2,3,null,5]
输出:[“1->2->5”,“1->3”]
时间复杂度 O(n)
1、从根结点出发,递归走所有的路径,并把路径的值记录下来
2、递归过程中
若左子树和右子树都为null,则返回记录的路径s
若左子树不为null,则把左子树的值加入到路径中,递归到左子树
若右子树不为null,则把右子树的值加入到路径中,递归到右子树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<String> ans = new ArrayList<>();
public List<String> binaryTreePaths(TreeNode root) {
if(root == null) return ans ;
dfs(root,""+root.val);
return ans;
}
public void dfs(TreeNode root,String s){
if(root.left ==null && root.right ==null){
ans.add(s);
return ;
}
if(root.left != null) dfs(root.left,s + "->"+root.left.val);
if(root.right != null) dfs(root.right,s + "->"+root.right.val);
}
}