前言
书接上篇文章介绍的链表基础知识—>二叉树理论,这篇文章我们将通过习题来掌握哈希表的使用。
###我做这类文档一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴!!
共勉!
习题【力扣】
1.二叉树的前序遍历
ps:建议写之前把这篇文章啃完->二叉树的遍历
题目链接:144. 二叉树的前序遍历 - 力扣(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 {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
recursion(root,list);
return list;
}
public void recursion(TreeNode node, List<Integer> list){
if(node==null)return;
list.add(node.val);
recursion(node.left,list);
recursion(node.right,list);
}
}
迭代实现代码:
/**
* 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> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()&&root!=null){
TreeNode node = stack.pop();
list.add(node.val);
if(node.right!=null)stack.push(node.right);
if(node.left!=null)stack.push(node.left);
}
return list;
}
}
2.二叉树的中序遍历
题目链接:94. 二叉树的中序遍历 - 力扣(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 {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
recursion(root,list);
return list;
}
public void recursion(TreeNode node,List<Integer> list){
if(node==null)return;
if(node.left!=null)recursion(node.left,list);
list.add(node.val);
if(node.right!=null)recursion(node.right,list);
}
}
迭代代码:
/**
* 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> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while(root!=null||!stack.isEmpty()){
while(root!=null){
stack.push(root);
root = root.left;
}
TreeNode node = stack.pop();
list.add(node.val);
if(node.right!=null){
root = node.right;
}
}
return list;
}
}
3.二叉树的后序遍历
题目链接:145. 二叉树的后序遍历 - 力扣(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 {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
recursion(root,list);
return list;
}
public void recursion(TreeNode node,List<Integer> list){
if(node==null)return;
if(node.left!=null)recursion(node.left,list);
if(node.right!=null)recursion(node.right,list);
list.add(node.val);
}
}
迭代代码:
/**
* 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> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root==null)return list;
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
stack1.push(root);
while(!stack1.isEmpty()){
TreeNode node = stack1.pop();
stack2.push(node);
if(node.left!=null)stack1.push(node.left);
if(node.right!=null)stack1.push(node.right);
}
while(!stack2.isEmpty()){
list.add(stack2.pop().val);
}
return list;
}
}
4.翻转二叉树
题目链接:226. 翻转二叉树 - 力扣(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 {
public TreeNode invertTree(TreeNode root) {
Stack<Integer> stack = new Stack<>();
recursion(root);
return root;
}
public void recursion(TreeNode node){
if(node==null)return;
TreeNode flag = node.left;
node.left = node.right;
node.right = flag;
recursion(node.left);
recursion(node.right);
}
}
5.N叉树的前序遍历
题目链接:589. N 叉树的前序遍历 - 力扣(LeetCode)
题面:
基本分析:和二叉树的前序遍历一样,只不过把左右节点遍历改成了循环遍历
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<Integer> preorder(Node root) {
List<Integer> list = new ArrayList<>();
if(root==null)return list;
Stack<Node> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
Node node = stack.pop();
list.add(node.val);
if(node.children!=null){
for (int i =node.children.size()-1; i>=0; i--) {
stack.push(node.children.get(i));
}
}
}
return list;
}
}
// public void recursion(Node node, List<Integer> list){
// if(node==null)return;
// list.add(node.val);
// for (int i =0; i<node.children.size(); i++) {
// recursion(node.children.get(i),list);
// }
// }
// }
6.N叉树的后序遍历
题目链接:590. N 叉树的后序遍历 - 力扣(LeetCode)
题面:
基本分析:和二叉树的后序遍历一样,只不过把左右节点遍历改成了循环遍历
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
}
*/
class Solution {
public List<Integer> postorder(Node root) {
List<Integer> list = new ArrayList<>();
if (root == null)return list;
Stack<Node> stack1 = new Stack<>();
// recursion(root,list);
Stack<Node> stack2 = new Stack<>();
stack1.push(root);
while (!stack1.isEmpty()) {
System.out.println(1);
Node node = stack1.pop();
stack2.push(node);
for (int i = 0; i<node.children.size(); i++) {
stack1.push(node.children.get(i));
}
}
while(!stack2.isEmpty())list.add(stack2.pop().val);
return list;
}
// public void recursion(Node node,List<Integer> list){
// if(node==null)return;
// if(node.children.size()!=0){
// for(int i = 0;i<node.children.size();i++){
// recursion(node.children.get(i),list);
// }
// }
// list.add(node.val);
// }
}
7.对称二叉树
题目链接:101. 对称二叉树 - 力扣(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 {
public boolean isSymmetric(TreeNode root) {
if(root.left==null&&root.right==null)return true;
return resursion(root.left,root.right);
}
public boolean resursion(TreeNode left,TreeNode right){
if(left==null&&right==null)return true;
if(left==null||right==null)return false;
if(left.val!=right.val)return false;
boolean bool1 = resursion(left.left,right.right);
boolean bool2 = resursion(left.right,right.left);
return bool1&&bool2;
}
}
8. 相同的树
题面链接:100. 相同的树 - 力扣(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 {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null&&q==null)return true;
if(p==null||q==null)return false;
if(p.val!=q.val)return false;
return recursion(p.left,q.left)&&recursion(p.right,q.right);
}
public boolean recursion(TreeNode left,TreeNode right){
if(left==null&&right==null) return true;
if(left==null||right==null) return false;
boolean bool1 = recursion(left.left,right.left)||false;
boolean bool2 = recursion(left.right,right.right)||false;
// if(left.val!=right.val)return false;
// if(left.val==right.val)return true;
return bool1&&bool2&&left.val==right.val;
}
}
9.另一棵树的子树
题目链接:572. 另一棵树的子树 - 力扣(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 {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if(root==null&&subRoot==null){
return true;
}
if(root==null||subRoot==null){
return false;
}
if(root.val!=subRoot.val&&(root.left==null&&root.right==null)){
return false;
}
if(root.val==subRoot.val&&(root.left==null&&root.right==null)){
return true;
}
return recursion1(root,subRoot)||false;
}
public boolean recursion1(TreeNode node,TreeNode subRoot){
if(node==null){
return false;
}
if(node.val==subRoot.val){
boolean bool1 = recursion2(node.left,subRoot.left);
boolean bool2 = recursion2(node.right,subRoot.right);
if(bool1&&bool2){
return true;
}
}
return recursion1(node.left, subRoot)||recursion1(node.right, subRoot);
}
public boolean recursion2(TreeNode node1,TreeNode node2){
if(node1==null&&node2==null){
return true;
}
if(node1==null||node2==null){
return false;
}
boolean bool1 = recursion2(node1.left,node2.left);
boolean bool2 = recursion2(node1.right,node2.right);
return bool1&&bool2&&node1.val==node2.val;
}
}
// /**
// * 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 boolean isSubtree(TreeNode s, TreeNode t) {
if (t == null) return true; // t 为 null 一定都是 true
if (s == null) return false; // 这里 t 一定不为 null, 只要 s 为 null,肯定是 false
return isSubtree(s.left, t) || isSubtree(s.right, t) || isSameTree(s,t);
}
/**
* 判断两棵树是否相同
*/
public boolean isSameTree(TreeNode s, TreeNode t){
if (s == null && t == null) return true;
if (s == null || t == null) return false;
if (s.val != t.val) return false;
return isSameTree(s.left, t.left) && isSameTree(s.right, t.right);
}
}
10. 二叉树的最大深度
题目链接:104. 二叉树的最大深度 - 力扣(LeetCode)
题面:
基本分析:维护一个max,用来记录最大值
/**
* 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 maxDepth(TreeNode root) {
if(root==null)return 0;
return recursion(root,1,1);
}
public int recursion(TreeNode node,int count,int max){
if(node==null)return max;
max = Math.max(recursion(node.left,count+1,max),max);
max = Math.max(recursion(node.right,count+1,max),max);
max = Math.max(count,max);
return max;
}
}
11.二叉树的最小深度
题目链接:111. 二叉树的最小深度 - 力扣(LeetCode)
题面:
基本分析: 维护一个min,在递归到下一层无子节点时就更新min。
代码:
/**
* 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 minDepth(TreeNode root) {
if(root==null){
return 0;
}
return recursion(root,1,Integer.MAX_VALUE);
}
public int recursion(TreeNode node,int count,int min){
if(node.left!=null){
min = Math.min(min,recursion(node.left,count+1,min));
}
if(node.right!=null){
min = Math.min(min,recursion(node.right,count+1,min));
}
if(node.left==null&&node.right==null){
return min = count;
}
return min;
}
}
后言
上面是二叉树的部分习题,下一篇会讲解二叉树的其他相关力扣习题,希望有所帮助,一同进步,共勉!