二叉树题目
- 1. 二叉树遍历
- 2. 如何直观打印一棵二叉树
- 3. 二叉树递归套路 (树形dp)
- 4. 在二叉树中序遍历中找到一个节点的后继节点(前驱节点)
- 5. 二叉树的序列化与反序列化
- 6. 判断一棵树是否是另一棵树的子树
- 7. 折纸问题
- 8. 二叉树和为某值的路径
- 9. 搜索二叉树
- 10. 已知先序和中序求后序
- 11. 搜索二叉树转双向链表
- 12. 完全二叉树节点数
- 13. 二叉搜索树的最小绝对差 (中序非递归遍历)
- 14. 二叉树的镜像
- 15. 对称的二叉树
- 16. 合并二叉树
- 17. 二叉搜索树节点最小距离
- 18. 二叉搜索树的第k大节点
- 19. 叶子相似的树
- 20. N叉树遍历
- 21. 递增顺序搜索树
- 22. BiNode
- 23. 根据二叉树创建字符串
- 24. 将有序数组转换为二叉搜索树
- 25. 最小高度树
1. 二叉树遍历
1.1 先序遍历
1.1.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 {
List<Integer>list=new ArrayList<>();
public List<Integer> preorderTraversal(TreeNode root) {
if(root==null)return list;
list.add(root.val);
preorderTraversal(root.left);
preorderTraversal(root.right);
return list;
}
}
1.1.2 非递归遍历
/**
* 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<>();
if(root==null)return list;
Stack<TreeNode>st=new Stack<>();
TreeNode cur=null;
st.push(root);
while(!st.isEmpty()){
cur=st.pop();
list.add(cur.val);
if(cur.right!=null) st.push(cur.right);
if(cur.left!=null)st.push(cur.left);
}
return list;
}
}
1.2 中序遍历
1.2.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 {
List<Integer> list=new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
if(root==null)return list;
inorderTraversal(root.left);
list.add(root.val);
inorderTraversal(root.right);
return list;
}
}
1.2.2 非递归遍历
/**
* 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<>();
if(root==null)return list;
Stack<TreeNode>st=new Stack<>();
TreeNode cur=root;
while(!st.isEmpty()||cur!=null){
if(cur!=null){//左边界入栈
st.push(cur);
cur=cur.left;
}
else{
cur=st.pop();
list.add(cur.val);
cur=cur.right;
}
}
return list;
}
}
1.3 后序遍历
1.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 {
List<Integer>list=new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
if(root==null)return list;
postorderTraversal(root.left);
postorderTraversal(root.right);
list.add(root.val);
return list;
}
}
1.3.2 非递归遍历
/**
* 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>st1=new Stack<>();
Stack<Integer>st2=new Stack<>();
TreeNode cur=null;
if(root==null)return list;
st1.push(root);
while(!st1.isEmpty()){
cur=st1.pop();
st2.push(cur.val);
if(cur.left!=null)st1.push(cur.left);
if(cur.right!=null)st1.push(cur.right);
}
while(!st2.isEmpty()){
list.add(st2.pop());
}
return list;
}
}
1.4 二叉树层序遍历
1.4.1 不分层打印
package demo05;
import java.util.LinkedList;
import java.util.Queue;
public class LevelTraversal {
public static class Node{
public int val;
public Node left;
public Node right;
public Node(int val) {
this.val=val;
left=null;
right=null;
}
}
public static void print(Node head) {
Queue<Node>queue=new LinkedList<>();
if(head==null)return;
queue.add(head);
Node cur=null;
while(!queue.isEmpty()) {
cur=queue.poll();
System.out.println(cur.val);
if(cur.left!=null)queue.add(cur.left);
if(cur.right!=null)queue.add(cur.right);
}
}
public static void main(String[] args) {
Node head=new Node(1);
head.left=new Node(2);
head.right=new Node(3);
head.left.right=new Node(4);
head.right.right=new Node(5);
print(head);
}
}
1.4.2 分层打印
/**
* 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<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>>list=new ArrayList<List<Integer>>();
if(root==null)return list;
Map<TreeNode,Integer>levelMap=new HashMap<>();
levelMap.put(root,1);
Queue<TreeNode>queue=new LinkedList<>();
queue.add(root);
int maxLevelNodes=0;
int curLevel=1;
int nodes=0;
TreeNode cur=null;
List<Integer>tmp=new ArrayList<>();
while(!queue.isEmpty()){
cur=queue.poll();
if(levelMap.get(cur)==curLevel){
nodes++;
tmp.add(cur.val);
}
else{
list.add(tmp);
tmp=new ArrayList<Integer>();
maxLevelNodes=maxLevelNodes>nodes?maxLevelNodes:nodes;
nodes=1;
tmp.add(cur.val);
curLevel++;
}
if(cur.left!=null){
levelMap.put(cur.left,levelMap.get(cur)+1);
queue.add(cur.left);
}
if(cur.right!=null){
levelMap.put(cur.right,levelMap.get(cur)+1);
queue.add(cur.right);
}
}
list.add(tmp);
return list;
}
}
1.4.3 二叉树最大宽度
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 求这可树的最大宽度
* @param head TreeNode类 树的根节点
* @return int整型
*/
public int getMaxWidth (TreeNode head) {
// write code here
if(head==null)return 0;
Map<TreeNode,Integer>levelMap=new HashMap<>();
levelMap.put(head,1);
Queue<TreeNode>queue=new LinkedList<>();
queue.add(head);
int maxLevelNodes=0;
int curLevel=1;
int nodes=0;
TreeNode cur=null;
while(!queue.isEmpty()){
cur=queue.poll();
if(levelMap.get(cur)==curLevel){
nodes++;
}
else{
maxLevelNodes=maxLevelNodes>nodes?maxLevelNodes:nodes;
nodes=1;
curLevel++;
}
if(cur.left!=null){
levelMap.put(cur.left,levelMap.get(cur)+1);
queue.add(cur.left);
}
if(cur.right!=null){
levelMap.put(cur.right,levelMap.get(cur)+1);
queue.add(cur.right);
}
}
maxLevelNodes=maxLevelNodes>nodes?maxLevelNodes:nodes;
return maxLevelNodes;
}
}
1.4.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 int maxDepth(TreeNode root) {
if(root==null)return 0;
Map<TreeNode,Integer>levelMap=new HashMap<>();
levelMap.put(root,1);
Queue<TreeNode>queue=new LinkedList<>();
queue.add(root);
int maxLevelNodes=0;
int curLevel=1;
int nodes=0;
TreeNode cur=null;
while(!queue.isEmpty()){
cur=queue.poll();
if(levelMap.get(cur)==curLevel){
nodes++;
}
else{
maxLevelNodes=maxLevelNodes>nodes?maxLevelNodes:nodes;
nodes=1;
curLevel++;
}
if(cur.left!=null){
levelMap.put(cur.left,levelMap.get(cur)+1);
queue.add(cur.left);
}
if(cur.right!=null){
levelMap.put(cur.right,levelMap.get(cur)+1);
queue.add(cur.right);
}
}
return curLevel;
}
}
1.4.5 二叉树之字形层序遍历
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>>list=new ArrayList<ArrayList<Integer>>();
if(pRoot==null)return list;
Map<TreeNode,Integer>levelMap=new HashMap<>();
levelMap.put(pRoot,1);
Queue<TreeNode>queue=new LinkedList<>();
queue.add(pRoot);
int maxLevelNodes=0;
int curLevel=1;
int nodes=0;
TreeNode cur=null;
ArrayList<Integer>tmp=new ArrayList<>();
while(!queue.isEmpty()){
cur=queue.poll();
if(levelMap.get(cur)==curLevel){
nodes++;
tmp.add(cur.val);
}
else{
if(curLevel%2==0)Collections.reverse(tmp);
list.add(tmp);
tmp=new ArrayList<Integer>();
maxLevelNodes=maxLevelNodes>nodes?maxLevelNodes:nodes;
nodes=1;
tmp.add(cur.val);
curLevel++;
}
if(cur.left!=null){
levelMap.put(cur.left,levelMap.get(cur)+1);
queue.add(cur.left);
}
if(cur.right!=null){
levelMap.put(cur.right,levelMap.get(cur)+1);
queue.add(cur.right);
}
}
if(curLevel%2==0)Collections.reverse(tmp);
list.add(tmp);
return list;
}
}
1.4.6 如何判断一棵树是完全二叉树
/**
* 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 isCompleteTree(TreeNode root) {
if(root==null)return true;
Queue<TreeNode>queue=new LinkedList<>();
TreeNode cur=null;
queue.add(root);
boolean isMeet2=false;//标记
while(!queue.isEmpty()){
cur=queue.poll();
if(cur.right!=null&&cur.left==null||isMeet2&&!(cur.left==null&&cur.right==null)){
return false;
}
if(cur.left!=null){
queue.add(cur.left);
}
if(cur.right!=null){
queue.add(cur.right);
}
if(!(cur.left!=null&&cur.right!=null))isMeet2=true;
}
return true;
}
}
1.5 Morris遍历 (为面试增色)
M o r r i s Morris Morris 遍历可以改出来二叉树的先序、中序和后序遍历(这三种遍历方式无论是利用递归也好,还是迭代也好,时间复杂度是 O ( N ) O(N) O(N) ,空间复杂度是 O ( l o g N ) O(logN) O(logN) ), 而 M o r r i s Morris Morris 遍历的时间复杂度是 O ( N ) O(N) O(N) , 空间复杂度是 O ( 1 ) O(1) O(1) 。
1.5.1 Morris遍历序
M o r r i s Morris Morris 遍历序 :
package demo13;
import java.util.Scanner;
public class MorrisTravesal {
public static class Node{
public int val;
public Node lchild;
public Node rchild;
public Node(int v) {
val=v;
}
}
public static void Morris(Node head) {
if(head==null)return;
Node cur=head;
Node mostRightNode=null;
while(cur!=null) {
System.out.print(cur.val+" ");
mostRightNode=cur.lchild;
if(mostRightNode!=null) {//有左树
while(mostRightNode.rchild!=null&&mostRightNode.rchild!=cur) {
mostRightNode=mostRightNode.rchild;
}
if(mostRightNode.rchild==null) {
mostRightNode.rchild=cur;
cur=cur.lchild;
}else {
mostRightNode.rchild=null;
cur=cur.rchild;
}
}
else {//无左树
cur=cur.rchild;
}
}
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
Node head=new Node(1);
head.lchild=new Node(2);
head.lchild.lchild=new Node(4);
head.lchild.rchild=new Node(5);
head.rchild=new Node(3);
head.rchild.lchild=new Node(6);
head.rchild.rchild=new Node(7);
Morris(head);
}
}
1.5.2 Morris遍历 改二叉树先序遍历
L e e t c o d e Leetcode Leetcode 144 题
/**
* 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> MorrisPreOrder(TreeNode head) {
List<Integer>list=new ArrayList<>();
if(head==null)return list;
TreeNode cur=head;
TreeNode mostRightNode=null;
while(cur!=null) {
mostRightNode=cur.left;
if(mostRightNode!=null) {//有左树
while(mostRightNode.right!=null&&mostRightNode.right!=cur) {
mostRightNode=mostRightNode.right;
}
if(mostRightNode.right==null) {
list.add(cur.val);//有左树的节点,第一次就打印
mostRightNode.right=cur;
cur=cur.left;
}else {
mostRightNode.right=null;
cur=cur.right;
}
}
else {//无左树
list.add(cur.val);
cur=cur.right;
}
}
return list;
}
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer>list=MorrisPreOrder(root);
return list;
}
}
1.5.3 Morris遍历 改二叉树中序遍历
L e e t c o d e Leetcode Leetcode 94 题
/**
* 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> MorrisPreOrder(TreeNode head) {
List<Integer>list=new ArrayList<>();
if(head==null)return list;
TreeNode cur=head;
TreeNode mostRightNode=null;
while(cur!=null) {
mostRightNode=cur.left;
if(mostRightNode!=null) {//有左树
while(mostRightNode.right!=null&&mostRightNode.right!=cur) {
mostRightNode=mostRightNode.right;
}
if(mostRightNode.right==null) {
mostRightNode.right=cur;
cur=cur.left;
}else {
list.add(cur.val);
mostRightNode.right=null;
cur=cur.right;
}
}
else {//无左树
list.add(cur.val);
cur=cur.right;
}
}
return list;
}
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer>list=MorrisPreOrder(root);
return list;
}
}
1.5.4 Morris遍历 改二叉树后序遍历
L e e t c o d e Leetcode Leetcode 145 题
/**
* 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> Morris(TreeNode head) {
TreeNode cur=head;
TreeNode mostRightNode=null;
List<Integer>list=new ArrayList<>();
if(head==null)return list;
while(cur!=null) {
mostRightNode=cur.left;
if(mostRightNode!=null) {//有左树
while(mostRightNode.right!=null&&mostRightNode.right!=cur) {
mostRightNode=mostRightNode.right;
}
if(mostRightNode.right==null) {
mostRightNode.right=cur;
cur=cur.left;
}else {
mostRightNode.right=null;
getRightEdge(list,cur.left);
cur=cur.right;
}
}
else {//无左树
cur=cur.right;
}
}
getRightEdge(list,head);
return list;
}
public void getRightEdge( List<Integer>list,TreeNode node){
//if(node==null)return;
TreeNode head=reverse(node);
TreeNode tail=head;
while(head!=null){
list.add(head.val);
head=head.right;
}
reverse(tail);
}
public TreeNode reverse(TreeNode node){
TreeNode pre=null;
TreeNode next=null;
while(node!=null){
next=node.right;
node.right=pre;
pre=node;
node=next;
}
return pre;
}
public List<Integer> postorderTraversal(TreeNode root) {
return Morris(root);
}
}
1.5.5 Morris 中序遍历判断一棵树是否是二叉搜索树
L e e t c o d e Leetcode Leetcode 98 题
提示: 变量 i s F i r s t isFirst isFirst 设立的目的是为了判断是否是第一个中序遍历节点,中序遍历的第一个节点满足 B S T BST BST ,有可能与一开始设置的 p r e V a l u e preValue preValue相等 ,而非第一个节点,要求满足严格大于 p r e V a l u e preValue preValue 。
空间复杂度 O ( 1 ) O(1) O(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 boolean MorrisInOrder_BST(TreeNode head) {
if(head==null)return true;
TreeNode cur=head;
TreeNode mostRightNode=null;
int preValue=Integer.MIN_VALUE;
boolean isFirst=true;
while(cur!=null) {
mostRightNode=cur.left;
if(mostRightNode!=null) {//有左树
while(mostRightNode.right!=null&&mostRightNode.right!=cur) {
mostRightNode=mostRightNode.right;
}
if(mostRightNode.right==null) {
mostRightNode.right=cur;
cur=cur.left;
}else {
if(isFirst){
if(cur.val<preValue){
return false;
}
isFirst=false;
}
else{
if(cur.val<=preValue){
return false;
}
}
preValue=cur.val;
mostRightNode.right=null;
cur=cur.right;
}
}
else {//无左树
if(isFirst){
if(cur.val<preValue){
return false;
}
isFirst=false;
}
else{
if(cur.val<=preValue){
return false;
}
}
preValue=cur.val;
cur=cur.right;
}
}
return true;
}
public boolean isValidBST(TreeNode root) {
return MorrisInOrder_BST(root);
}
}
2. 如何直观打印一棵二叉树
纯粹是 c o d i n g coding coding 上的技巧,不涉及算法, 方便解题 。
public class PrintBinaryTree {
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static void printTree(Node head) {
System.out.println("Binary Tree:");
printInOrder(head, 0, "H", 17);
System.out.println();
}
public static void printInOrder(Node head, int height, String to, int len) {
if (head == null) {
return;
}
printInOrder(head.right, height + 1, "v", len);
String val = to + head.value + to;
int lenM = val.length();
int lenL = (len - lenM) / 2;
int lenR = len - lenM - lenL;
val = getSpace(lenL) + val + getSpace(lenR);
System.out.println(getSpace(height * len) + val);
printInOrder(head.left, height + 1, "^", len);
}
public static String getSpace(int num) {
String space = " ";
StringBuffer buf = new StringBuffer("");
for (int i = 0; i < num; i++) {
buf.append(space);
}
return buf.toString();
}
public static void main(String[] args) {
Node head = new Node(1);
head.left = new Node(-222222222);
head.right = new Node(3);
head.left.left = new Node(Integer.MIN_VALUE);
head.right.left = new Node(55555555);
head.right.right = new Node(66);
head.left.left.right = new Node(777);
printTree(head);
head = new Node(1);
head.left = new Node(2);
head.right = new Node(3);
head.left.left = new Node(4);
head.right.left = new Node(5);
head.right.right = new Node(6);
head.left.left.right = new Node(7);
printTree(head);
head = new Node(1);
head.left = new Node(1);
head.right = new Node(1);
head.left.left = new Node(1);
head.right.left = new Node(1);
head.right.right = new Node(1);
head.left.left.right = new Node(1);
printTree(head);
}
}
3. 二叉树递归套路 (树形dp)
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 static class Info{
public boolean isBST;
public int minVal;
public int maxVal;
public Info(boolean isBST,int minVal,int maxVal){
this.isBST=isBST;
this.minVal=minVal;
this.maxVal=maxVal;
}
}
public static Info process(TreeNode root){
if(root==null)return null;
Info leftInfo=process(root.left);
Info rightInfo=process(root.right);
int min=root.val;
int max=root.val;
if(leftInfo!=null){
min=min<leftInfo.minVal?min:leftInfo.minVal;
max=max>leftInfo.maxVal?max:leftInfo.maxVal;
}
if(rightInfo!=null){
min=min<rightInfo.minVal?min:rightInfo.minVal;
max=max>rightInfo.maxVal?max:rightInfo.maxVal;
}
boolean isBST=false;
if(
(leftInfo==null?true:leftInfo.maxVal<root.val&&leftInfo.isBST)
&&
(rightInfo==null?true:rightInfo.minVal>root.val&&rightInfo.isBST)
){isBST=true;}
return new Info(isBST,min,max);
}
public boolean isValidBST(TreeNode root) {
Info info=process(root);
return info.isBST;
}
}
3.2 判断一棵树是否是满二叉树
package demo05;
public class IsFullBinaryTree {
public static class Node{
public int val;
public Node left;
public Node right;
public Node(int val) {
this.val=val;
left=null;
right=null;
}
}
public static class Info{
public int nodes;
public int height;
public Info(int nodes,int height) {
this.nodes=nodes;
this.height=height;
}
}
public static boolean isFull(Node head) {
Info info=process(head);
int N=info.nodes;
int H=info.height;
return N==(1<<H)-1;
}
public static Info process(Node head) {
if(head==null)return new Info(0,0);
Info leftInfo=process(head.left);
Info rightInfo=process(head.right);
int nodes=leftInfo.nodes+rightInfo.nodes+1;
int height=Math.max(leftInfo.height, rightInfo.height)+1;
return new Info(nodes,height);
}
public static void main(String[] args) {
Node head1=new Node(1);
head1.left=new Node(2);
head1.right=new Node(3);
head1.right.left=new Node(4);
boolean b=isFull(head1);
System.out.println(b);
}
}
二叉搜索树 的 中序 遍历是 递增 序列
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}*/
public class Checker {
public static void inOrder(TreeNode root,List<Integer>list){
if(root==null)return ;
inOrder(root.left,list);
list.add(root.val);
inOrder(root.right,list);
}
public boolean checkBST(TreeNode root) {
// write code here
List<Integer>list=new ArrayList<>();
inOrder(root,list);
for(int i=0;i<list.size()-1;++i){
if(list.get(i)>list.get(i+1))return false;
}
return true;
}
}
3.3 判断一棵树是否是平衡二叉树
/**
* 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 class Info{
public boolean isBalanced;
public int height;
public Info(boolean isBalanced,int height){
this.isBalanced=isBalanced;
this.height=height;
}
}
public Info process(TreeNode root){
if(root==null)return new Info(true,0);
Info leftInfo=process(root.left);
Info rightInfo=process(root.right);
boolean isBalanced=false;
int height=Math.max(leftInfo.height,rightInfo.height)+1;
if(
leftInfo.isBalanced==true
&&
rightInfo.isBalanced==true
&&
Math.abs(leftInfo.height-rightInfo.height)<2
)isBalanced=true;
return new Info(isBalanced,height);
}
public boolean isBalanced(TreeNode root) {
Info info=process(root);
return info.isBalanced;
}
}
3.4 最近公共祖先
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public class Info{
public boolean isFind_p;
public boolean isFind_q;
public TreeNode ancestor;
public Info(boolean isFind_p,boolean isFind_q,TreeNode ancestor){
this.isFind_p=isFind_p;
this.isFind_q=isFind_q;
this.ancestor=ancestor;
}
}
public Info process(TreeNode x,TreeNode p,TreeNode q){
if(x==null)return new Info(false,false,null);
Info leftInfo=process(x.left,p,q);
Info rightInfo=process(x.right,p,q);
//p,q同时在左子树或者右子树上
if(leftInfo.ancestor!=null){
return new Info(true,true,leftInfo.ancestor);
}
if(rightInfo.ancestor!=null){
return new Info(true,true,rightInfo.ancestor);
}
//p,q分别位于左子树和右子树上
if(leftInfo.isFind_p&&rightInfo.isFind_q||leftInfo.isFind_q&&rightInfo.isFind_p){
return new Info(true,true,x);
}
//p,q至多有一个位于左子树或者右子树上
if(leftInfo.isFind_p||rightInfo.isFind_p){
if(x==q)return new Info(true,true,x);
else return new Info(true,false,null);
}
if(leftInfo.isFind_q||rightInfo.isFind_q){
if(x==p)return new Info(true,true,x);
else return new Info(false,true,null);
}
return new Info(x==p,x==q,null);
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
Info info=process(root,p,q);
return info.ancestor;
}
}
3.5 最大二叉搜索子树
L e e t c o d e Leetcode Leetcode 333题
注意: l e f t I n f o = = n u l l ? 0 : l e f t I n f o . m a x B S T leftInfo==null?0:leftInfo.maxBST leftInfo==null?0:leftInfo.maxBST 要加 括号,否则会发生 逻辑错误
/**
* 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 class Info{
public int maxBST;
public int max;
public int min;
public boolean isBST;
public Info(int a,int b,int c,boolean d){
maxBST=a;
max=b;
min=c;
isBST=d;
}
}
public Info process(TreeNode x){
if(x==null)return new Info(0,Integer.MIN_VALUE,Integer.MAX_VALUE,true);
Info leftInfo=process(x.left);
Info rightInfo=process(x.right);
int max=Math.max(Math.max(leftInfo==null?Integer.MIN_VALUE:leftInfo.max,rightInfo==null?Integer.MIN_VALUE:rightInfo.max),x.val);
int min=Math.min(Math.min(leftInfo==null?Integer.MAX_VALUE:leftInfo.min,rightInfo==null?Integer.MAX_VALUE:rightInfo.min),x.val);
int maxBST=Math.max(leftInfo==null?0:leftInfo.maxBST,rightInfo==null?0:rightInfo.maxBST);
boolean isBST=false;
if((leftInfo==null?true:leftInfo.isBST)&& (rightInfo==null?true:rightInfo.isBST) &&(leftInfo==null?true:leftInfo.max<x.val) && (rightInfo==null?true:rightInfo.min>x.val)){
maxBST=(leftInfo==null?0:leftInfo.maxBST)+(rightInfo==null?0:rightInfo.maxBST)+1;
isBST=true;
}
return new Info(maxBST,max,min,isBST);
}
public int largestBSTSubtree(TreeNode root) {
return process(root).maxBST;
}
}
3.6 派对的最大快乐值
知识点:题目中用到了加速输入的方法
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class Main {
private static final StreamTokenizer st
= new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static int nextInt() {
try {
st.nextToken();
return (int) st.nval;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static class TreeNode{
public int val;
public int happy;
public List<TreeNode> nexts;
public TreeNode(int v,int h) {
val=v;
happy=h;
nexts=new ArrayList<>();
}
}
public static class Info{
public int headYes;
public int headNo;
public Info(int a,int b) {
headYes=a;
headNo=b;
}
}
public static Info process(TreeNode x) {
if(x.nexts.isEmpty())return new Info(x.happy,0);
int headYes=x.happy,headNo=0;
for(TreeNode next:x.nexts) {
Info info=process(next);
headYes+=info.headNo;
headNo+=Math.max(info.headYes,info.headNo);
}
return new Info(headYes,headNo);
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int N=nextInt();
Map<Integer,TreeNode>map=new HashMap<>();
Set<Integer>set=new HashSet<>();
for(int i=1;i<=N;++i) {
map.put(i, new TreeNode(i,nextInt()));
}
int child,p;
for(int i=0;i<N-1;++i) {
child=nextInt();
set.add(child);
p=nextInt();
map.get(p).nexts.add(map.get(child));
}
nextInt();
nextInt();
TreeNode root=null;
for(int i=1;i<=N;++i) {
if(!set.contains(i)) {
root=map.get(i);break;
}
}
Info info=process(root);
System.out.println(Math.max(info.headYes, info.headNo));
}
}
3.7 二叉树节点间的最大距离问题
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static class Node{
public int value;
public Node lchild;
public Node rchild;
public Node(int a) {
value=a;
}
}
public static class Info{
public int maxDistance;
public int height;
public Info(int a,int b) {
maxDistance=a;
height=b;
}
}
public static void maxDistance(Node x) {
System.out.println(process(x).maxDistance);
}
public static Info process(Node x) {
if(x==null)return null;
Info leftInfo=process(x.lchild);
Info rightInfo=process(x.rchild);
int maxDistance,height;
height=Math.max(leftInfo==null?0:leftInfo.height,rightInfo==null?0:rightInfo.height)+1;
maxDistance=Math.max(leftInfo==null?0:leftInfo.maxDistance, rightInfo==null?0:rightInfo.maxDistance);
maxDistance=Math.max(maxDistance,(leftInfo==null?0:leftInfo.height)+(rightInfo==null?0:rightInfo.height)+1 );
return new Info(maxDistance,height);
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int N=scan.nextInt();
int rootValue=scan.nextInt();
Map<Integer,Node>map=new HashMap<>();
map.put(rootValue, new Node(rootValue));
for(int i=0;i<N;++i) {
int head=scan.nextInt();
int left=scan.nextInt();
int right=scan.nextInt();
if(!map.containsKey(head)) {
map.put(head,new Node(head));
}
if(!map.containsKey(left)) {
if(left!=0) {
map.put(left, new Node(left));
}
}
if(!map.containsKey(right)) {
if(right!=0) {
map.put(right, new Node(right));
}
}
if(map.containsKey(left))map.get(head).lchild=map.get(left);
if(map.containsKey(right))map.get(head).rchild=map.get(right);
}
maxDistance(map.get(rootValue));
}
}
3.8 二叉树权值和最大路径
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static class TreeNode{
public int val;
public int weight;
public TreeNode left;
public TreeNode right;
public TreeNode(int v,int w) {
val=v;
weight=w;
}
}
public static class Info{
public int maxPath;
public Info(int x)
{
maxPath=x;
}
}
public static Info process(TreeNode x) {
if(x==null)return null;
Info leftInfo=process(x.left);
Info rightInfo=process(x.right);
int maxPath=x.weight;
maxPath=Math.max(maxPath+(leftInfo==null?0:leftInfo.maxPath), maxPath+(rightInfo==null?0:rightInfo.maxPath));
return new Info(maxPath);
}
public static int getMaxPath(TreeNode root) {
Info info=process(root);
return info.maxPath;
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
Map<Integer,TreeNode>map=new HashMap<>();
int w,father;
TreeNode root=null;
for(int i=1;i<=n;++i) {
w=scan.nextInt();
father=scan.nextInt();
map.put(i, new TreeNode(i,w));
if(father==0)root=map.get(i);
else {
if(map.get(father).left==null)map.get(father).left=map.get(i);
else map.get(father).right=map.get(i);
}
}
System.out.println(getMaxPath(root));
}
}
3.9 二叉树结构计数
import java.util.Scanner;
public class Main {
public static int ways(int n) {
if(n<0)return 0;
if(n<=1)return 1;
if(n==2)return 2;
int ans=0;
for(int i=0;i<=n-1;++i) {
int leftWays=ways(i)%1000000007;
int rightWays=ways(n-1-i)%1000000007;
ans+=(leftWays*rightWays)%1000000007;
}
return ans%1000000007;
}
public static long waysDP(int n) {
if(n<0)return 0;
long[] dp=new long[n+1];
dp[0]=1;
for(int i=1;i<=n;++i) {
for(int j=0;j<=i-1;++j) {
dp[i]=dp[i]%1000000007+(dp[j]*dp[i-1-j])%1000000007;
}
}
return dp[n]%1000000007;
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
System.out.println(waysDP(n));
}
}
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 static class Info{
public long uncovered;
public long coveredNoCamera;
public long coveredYesCamera;
public Info(long a,long b,long c){
uncovered=a;
coveredNoCamera=b;
coveredYesCamera=c;
}
}
public static Info process(TreeNode x){
if(x==null){
return new Info(Integer.MAX_VALUE,0,Integer.MAX_VALUE);
}
Info leftInfo=process(x.left);
Info rightInfo=process(x.right);
long uncovered=leftInfo.coveredNoCamera+rightInfo.coveredNoCamera;
long coveredNoCamera;
long coveredYesCamera;
coveredNoCamera=Math.min(
leftInfo.coveredYesCamera+rightInfo.coveredNoCamera,
Math.min(
leftInfo.coveredNoCamera+rightInfo.coveredYesCamera,
leftInfo.coveredYesCamera+rightInfo.coveredYesCamera
)
);
coveredYesCamera=Math.min(
leftInfo.uncovered,
Math.min(
leftInfo.coveredNoCamera,
leftInfo.coveredYesCamera
)
)
+
Math.min(
rightInfo.uncovered,
Math.min(
rightInfo.coveredNoCamera,
rightInfo.coveredYesCamera
)
)
+1;
return new Info(uncovered,coveredNoCamera,coveredYesCamera);
}
public int minCameraCover(TreeNode root) {
Info rootInfo=process(root);
return (int)Math.min(rootInfo.coveredNoCamera,Math.min(rootInfo.uncovered+1,rootInfo.coveredYesCamera));
}
}
4. 在二叉树中序遍历中找到一个节点的后继节点(前驱节点)
(面试第一题的难度)
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class Main {
public static class Node{
public int val;
public Node left=null;
public Node right=null;
public Node parent=null;
public Node(int val) {
this.val=val;
}
}
public static Node inorderSuccessor(Node root, Node p) {
if(p==null||root==null)return null;
if(p.right!=null){
return getMostLeftNode(p.right);
}
Node parent=p.parent;
Node cur=p;
while(parent!=null&&parent.right==cur) {
cur=parent;
parent=parent.parent;
}
return parent;
}
public static Node getMostLeftNode(Node x){
if(x==null)return null;
while(x.left!=null){
x=x.left;
}
return x;
}
public static void create() {
Node root=null;
Map<Integer,Node>hashMap=new HashMap<>();
int N,rootVal;
int a,b,c;
Scanner scan=new Scanner(System.in);
N=scan.nextInt();
rootVal=scan.nextInt();
root=new Node(rootVal);
hashMap.put(rootVal,root);
for(int i=0;i<N;++i) {
a=scan.nextInt();
b=scan.nextInt();
c=scan.nextInt();
if(!hashMap.containsKey(a)) {
hashMap.put(a, new Node(a));
}
if(b!=0) {
hashMap.put(b, new Node(b));
hashMap.get(a).left=hashMap.get(b);
hashMap.get(b).parent=hashMap.get(a);
}
if(c!=0) {
hashMap.put(c, new Node(c));
hashMap.get(a).right=hashMap.get(c);
hashMap.get(c).parent=hashMap.get(a);
}
}
Node p=hashMap.get(scan.nextInt());
Node ans=inorderSuccessor(root,p);
if(ans==null) {
System.out.println(0);
}
else System.out.println(ans.val);
}
public static void main(String[] args) {
create();
}
}
5. 二叉树的序列化与反序列化
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
import java.util.LinkedList;
import java.util.Queue;
class TreeNode{
public int val;
public TreeNode left=null;
public TreeNode right=null;
public TreeNode(int val) {
this.val=val;
}
}
public class Solution {
String Serialize(TreeNode root) {
if(root==null)return "#_";
String ans=root.val+"_";
ans+=Serialize(root.left);
ans+=Serialize(root.right);
return ans;
}
TreeNode Deserialize(String str) {
Queue<String>queue=new LinkedList<>();
String[] strs=str.split("_");
for(int i=0;i<strs.length;++i){
queue.add(strs[i]);
}
return process(queue);
}
public TreeNode process(Queue<String>queue){
TreeNode root=null;
String p=queue.poll();
if(p.equals("#"))return null;
root=new TreeNode(Integer.parseInt(p));
root.left=process(queue);
root.right=process(queue);
return root;
}
}
6. 判断一棵树是否是另一棵树的子树
/**
* 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 String Serialize(TreeNode root) {
if(root==null)return "#_";
String ans=root.val+"_";
ans+=Serialize(root.left);
ans+=Serialize(root.right);
return ans;
}
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
String s1=Serialize(root);
String s2=Serialize(subRoot);
int index=-1;
if((index=s1.indexOf(s2))!=-1){
if(index==0||(""+s1.charAt(index-1)).equals("_"))return true;
}
return false;
}
}
7. 折纸问题
最先在北美流行,后来流行到国内,属于曾经流行过,但是面试 可能会考 的题目。
import java.util.Scanner;
public class Main {
public static void paperFold(int N) {
process(1,N,true);
}
public static void process(int level,int N,boolean isDown) {
if(level>N)return;
process(level+1,N,true);
System.out.println(isDown?"down":"up");
process(level+1,N,false);
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int N=scan.nextInt();
paperFold(N);
}
}
8. 二叉树和为某值的路径
回溯+ 深度优先遍历
/**
* 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<List<Integer>> list=new ArrayList<>();
public void dfs(TreeNode node,int target,List<Integer>path){
if(node==null)return;
path.add(node.val);
target-=node.val;
if(node.left==null&&node.right==null&&target==0){//可以收集答案了
//因为在后续的递归层中, 这个path会被不断修改,你现在加进去的是个浅拷贝,
//修改的时候地址相同的引用全都跟着修改,但是你new一个新的path就是深拷贝,
//地址不同了,自然就不会出问题
list.add(new ArrayList<>(path));
}
else{
dfs(node.left,target,path);
dfs(node.right,target,path);
}
//还原现场
path.remove(path.size()-1);
}
public List<List<Integer>> pathSum(TreeNode root, int target) {
List<Integer>path=new ArrayList<>();
dfs(root,target,path);
return list;
}
}
二叉树Morris遍历代码:
public int[] Morris(TreeNode head) {//得到Morris序
List list=new ArrayList();;//存放Morris序
if(head==null)return null;
TreeNode cur=head;
TreeNode mostRightNode=null;
while(cur!=null) {
list.add(cur.value);
mostRightNode=cur.left;
if(mostRightNode!=null) {
while(mostRightNode.right!=null&&mostRightNode.right!=cur) {
mostRightNode=mostRightNode.right;
}
if(mostRightNode.right==null) {//第一次遍历到cur结点
mostRightNode.right=cur;
cur=cur.left;
continue;
}
else {//第二次遍历到cur结点
mostRightNode.right=null;
}
}
cur=cur.right;
}
int[] ans=new int[list.size()];
for(int i=0;i<list.size();++i)ans[i]=(int)list.get(i);
return ans;
}
Morris改二叉树前序遍历代码:
Leetcode上AC了
/**
* 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 list=new ArrayList();
if(root==null)return list;
TreeNode cur=root;
TreeNode mostRightNode=null;
while(cur!=null) {
mostRightNode=cur.left;
if(mostRightNode!=null) {
while(mostRightNode.right!=null&&mostRightNode.right!=cur) {
mostRightNode=mostRightNode.right;
}
if(mostRightNode.right==null) {
list.add(cur.val);
mostRightNode.right=cur;
cur=cur.left;
continue;
}
else {
mostRightNode.right=null;
}
}
else {
list.add(cur.val);
}
cur=cur.right;
}
return list;
}
}
Morris改二叉树中序遍历代码:
/**
* 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 list=new ArrayList();
if(root==null)return list;
TreeNode cur=root;
TreeNode mostRightNode=null;
while(cur!=null) {
mostRightNode=cur.left;
if(mostRightNode!=null) {
while(mostRightNode.right!=null&&mostRightNode.right!=cur) {
mostRightNode=mostRightNode.right;
}
if(mostRightNode.right==null) {
mostRightNode.right=cur;
cur=cur.left;
continue;
}
else {
mostRightNode.right=null;
}
}
list.add(cur.val);
cur=cur.right;
}
return list;
}
}
Morris改二叉树后序遍历代码:
/**
* 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 static void collectNodes(TreeNode head,List list) {//以head为头,逆序收集该树的右边界结点
TreeNode rear=reverseTree(head);
TreeNode cur=rear;
while(cur!=null) {
list.add(cur.val);
cur=cur.right;
}
reverseTree(rear);
}
public static TreeNode reverseTree(TreeNode from) {//逆序
TreeNode pre=null;
TreeNode next=null;
while(from!=null) {
next=from.right;
from.right=pre;
pre=from;
from=next;
}
return pre;
}
public List<Integer> postorderTraversal(TreeNode root) {
List list=new ArrayList();;//存放Morris序
if(root==null)return list;
TreeNode cur=root;
TreeNode mostRightNode=null;
while(cur!=null) {
// list.add(cur.value);
mostRightNode=cur.left;
if(mostRightNode!=null) {
while(mostRightNode.right!=null&&mostRightNode.right!=cur) {
mostRightNode=mostRightNode.right;
}
if(mostRightNode.right==null) {//第一次遍历到cur结点
mostRightNode.right=cur;
cur=cur.left;
continue;
}
else {//第二次遍历到cur结点
mostRightNode.right=null;
collectNodes(cur.left,list);//收集第二次遍历到的点的左子树结点
}
}
cur=cur.right;
}
collectNodes(root,list);//收集整棵树的右边界结点
return list;
}
}
视频链接:
https://space.bilibili.com/384453285
9. 搜索二叉树
package demo05;
//这里说明一下:经典的搜索二叉树节点值是不同的
public class BSTtest {
public static class Node{
public int value;
public Node lchild;
public Node rchild;
public Node(int value) {
this.value=value;
lchild=null;
rchild=null;
}
}
public static class BST{
public Node root;
public int size;
public BST() {
root=null;
size=0;
}
//增加
public void add(int value) {
size++;
if(root==null) {
root=new Node(value);
}
else {
Node cur=root;
Node parent=root;
while(cur!=null) {
parent=cur;
if(value<cur.value) {
cur=cur.lchild;
}
else {
cur=cur.rchild;
}
}
if(value<parent.value) {
parent.lchild=new Node(value);
}
else {
parent.rchild=new Node(value);
}
}
}
//查找
public boolean contains(int value) {//返回目标节点的父亲节点
Node cur=root;
while(cur!=null) {
if(cur.value==value) {
return true;
}
if(value<cur.value) {
cur=cur.lchild;
}
else {
cur=cur.rchild;
}
}
return false;
}
//删除
public void delete(int value) {
if(!contains(value))return;
size--;
Node cur=root;
Node parent=root;
while(cur!=null) {
if(!(parent.lchild.value==value||parent.rchild.value==value))parent=cur;
if(value==cur.value)break;
else if(value<cur.value) {
cur=cur.lchild;
}
else {
cur=cur.rchild;
}
}
// System.out.println(parent.value);
//分为4种情形:
if(cur.lchild==null&&cur.rchild==null) {
if(cur==root) {
root=null;
}
else if(parent.lchild==cur)parent.lchild=null;
else parent.rchild=null;
}
else if(cur.lchild==null) {
if(cur==root) {
root=cur.rchild;
cur.rchild=null;
}
else if(parent.lchild==cur) {
parent.lchild=cur.rchild;
cur.rchild=null;
}
else {
parent.rchild=cur.rchild;
cur.rchild=null;
}
}
else if(cur.rchild==null) {
if(cur==root) {
root=cur.lchild;
cur.lchild=null;
}
else if(parent.lchild==cur) {
parent.lchild=cur.lchild;
cur.lchild=null;
}
else {
parent.rchild=cur.lchild;
cur.lchild=null;
}
}
else {
Node p=cur.rchild;
Node q=p;
while(p.lchild!=null) {
q=p;
p=p.lchild;
}
q.lchild=p.rchild;
p.lchild=cur.lchild;
if(parent.lchild==cur) {
parent.lchild=p;
p.lchild=cur.lchild;
p.rchild=cur.rchild;
}
else{
parent.rchild=p;
p.lchild=cur.lchild;
p.rchild=cur.rchild;
}
if(cur==root) {
root=p;
}
}
}
}
public static void main(String[] args) {
BST bst=new BST();
bst.add(5);
bst.add(2);
bst.add(9);
bst.add(0);
bst.delete(9);
System.out.println(bst.contains(9));
System.out.println(bst.size);
}
}
10. 已知先序和中序求后序
import java.util.Scanner;
public class Main {
public static int[] getPostArray(int[] pre,int[] in,int n) {
if(n<1)return null;
int[] post=new int[n];
process(pre,0,n-1,in,0,n-1,post,0,n-1);
return post;
}
public static void process(int[] pre,int L1,int R1,int[] in,int L2,int R2,int[] post,int L3,int R3) {
if(L1<=R1) {
post[R3]=pre[L1];
if(L1==R1) {
return;
}
int index=0;
for(int i=L2;i<=R2;++i) {
if(in[i]==pre[L1]) {
index=i;break;
}
}
int left=index-L2;
int right=R2-index;
process(pre,L1+1,L1+left,in,L2,index-1,post,L3,L3+left-1);
process(pre,L1+left+1,R1,in,index+1,R2,post,L3+left,R3-1);
}
//else return;
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int[] pre=new int[n];
int[] in=new int[n];
for(int i=0;i<n;++i) {
pre[i]=scan.nextInt();
}
for(int i=0;i<n;++i) {
in[i]=scan.nextInt();
}
int[] post=getPostArray(pre,in,n);
for(int i=0;i<n;++i) {
System.out.print(post[i]+" ");
}
}
}
11. 搜索二叉树转双向链表
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class Main {
public static class TreeNode{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int v) {
val=v;
}
}
public static class Info{
public TreeNode start;
public TreeNode end;
public Info(TreeNode s,TreeNode e){
start=s;
end=e;
}
}
public static Info process(TreeNode x) {
if(x==null)return new Info(null,null);
Info leftInfo=process(x.left);
Info rightInfo=process(x.right);
if(leftInfo.end!=null) {
leftInfo.end.right=x;
}
x.left=leftInfo.end;
x.right=rightInfo.start;
if(rightInfo.start!=null) {
rightInfo.start.left=x;
}
return new Info((leftInfo.start==null?x:leftInfo.start),(rightInfo.end==null?x:rightInfo.end));
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
Set<Integer>set=new HashSet<>();
Map<Integer,TreeNode>map=new HashMap<>();
scan.nextLine();
for(int i=0;i<n;++i) {
String[] s=scan.nextLine().split(" ");
int father=Integer.parseInt(s[0]);
int l=Integer.parseInt(s[1]);
int r=Integer.parseInt(s[2]);
set.add(l);
set.add(r);
if(!map.containsKey(father))
map.put(father, new TreeNode(father));
if(l!=0) {
if(!map.containsKey(l)) {
map.put(l, new TreeNode(l));
}
map.get(father).left=map.get(l);
}
if(r!=0) {
if(!map.containsKey(r)) {
map.put(r, new TreeNode(r));
}
map.get(father).right=map.get(r);
}
}
TreeNode root=null;
for(int i=1;i<=n;++i) {
if(!set.contains(i)) {
root=map.get(i);
break;
}
}
TreeNode head=process(root).start;
TreeNode p=head;
StringBuffer s=new StringBuffer();
while(p!=null) {
// System.out.print(p.val+" ");
s.append(p.val+" ");
p=p.right;
}
System.out.print(s);
}
}
12. 完全二叉树节点数
时间复杂度 O ( ( l o g N ) 2 ) O((logN)^2) O((logN)2)
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}*/
public class Solution {
public int process(TreeNode node,int level,int N){
if(level==N)return 1;
if(getLevel(node.right,level+1)<N){//右树满
return process(node.left,level+1,N)+(1<<(getLevel(node.right,level+1)-level));
}else{//左树满
return process(node.right,level+1,N)+(1<<(N-level));
}
}
public int getLevel(TreeNode x,int level){
TreeNode p=x;
while(p!=null){
level++;
p=p.left;
}
return level-1;
}
public int nodeNum(TreeNode head) {
if(head==null)return 0;
return process(head,1,getLevel(head,1));
}
}
13. 二叉搜索树的最小绝对差 (中序非递归遍历)
/**
* 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 void leftEdge(TreeNode x,Stack<TreeNode>st){
while(x!=null){
st.push(x);
x=x.left;
}
}
public int getMinimumDifference(TreeNode root) {
int min=Integer.MAX_VALUE;
int pre=Integer.MAX_VALUE;
Stack<TreeNode>st=new Stack<>();
leftEdge(root,st);
while(!st.isEmpty()){
TreeNode cur=st.pop();
min=Math.min(min,Math.abs(pre-cur.val));
pre=cur.val;
leftEdge(cur.right,st);
}
return min;
}
}
14. 二叉树的镜像
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root==null){
return null;
}
TreeNode tmp=root.left;
root.left=mirrorTree(root.right);
root.right=mirrorTree(tmp);
return root;
}
}
15. 对称的二叉树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean process(TreeNode x,TreeNode y){
if(x==null&&y==null)return true;
if(x==null&&y!=null||y==null&&x!=null){
return false;
}
if(x.val!=y.val)return false;
return process(x.left,y.right)&&process(x.right,y.left);
}
public boolean isSymmetric(TreeNode root) {
if(root==null)return true;
return process(root,root);
}
}
16. 合并二叉树
/**
* 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 mergeTrees(TreeNode root1, TreeNode root2) {
if(root1==null&&root2==null)return null;
if(root1==null&&root2!=null)return root2;
if(root1!=null&&root2==null)return root1;
//root1,root2都不为null
TreeNode root=new TreeNode(root1.val+root2.val);
root.left=mergeTrees(root1.left,root2.left);
root.right=mergeTrees(root1.right,root2.right);
return root;
}
}
17. 二叉搜索树节点最小距离
/**
* 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 void leftEdge(Stack<TreeNode>st,TreeNode x){
while(x!=null){
st.push(x);
x=x.left;
}
}
public int minDiffInBST(TreeNode root) {
Stack<TreeNode>st=new Stack<>();
leftEdge(st,root);
int min=Integer.MAX_VALUE;
int pre=Integer.MAX_VALUE;
while(!st.isEmpty()){
TreeNode cur=st.pop();
leftEdge(st,cur.right);
min=Math.min(min,Math.abs(pre-cur.val));
pre=cur.val;
}
return min;
}
}
18. 二叉搜索树的第k大节点
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public void leftEdge(TreeNode x,Stack<TreeNode>st){
while(x!=null){
st.push(x);
x=x.left;
}
}
public int kthLargest(TreeNode root, int k) {
int index=0;
Stack<TreeNode>st=new Stack<>();
leftEdge(root,st);
List<Integer>list=new ArrayList<>();
while(!st.isEmpty()){
TreeNode cur=st.pop();
list.add(cur.val);
leftEdge(cur.right,st);
}
return list.get(list.size()-k);
}
}
19. 叶子相似的树
20. N叉树遍历
20.1 先序遍历
20.1.1 递归
/*
// 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 {
List<Integer>list=new ArrayList<>();
//递归
public void process(Node x){
if(x==null)return;
list.add(x.val);
for(Node node:x.children){
process(node);
}
}
public List<Integer> preorder(Node root) {
process(root);
return list;
}
}
20.1.2 非递归
/*
// 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>st=new Stack<>();
st.push(root);
while(!st.isEmpty()){
Node cur=st.pop();
list.add(cur.val);
for(int i=cur.children.size()-1;i>=0;--i){
st.push(cur.children.get(i));
}
}
return list;
}
}
20.2 后序遍历
20.2.1 递归
/*
// 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 {
List<Integer>list=new ArrayList<>();
public void process(Node x){
if(x==null)return;
for(Node node:x.children){
process(node);
}
list.add(x.val);
}
public List<Integer> postorder(Node root) {
process(root);
return list;
}
}
20.2.2 非递归
/*
// 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>st=new Stack<>();
st.push(root);
while(!st.isEmpty()){
Node cur=st.pop();
for(Node node:cur.children){
st.push(node);
}
list.add(cur.val);
}
Collections.reverse(list);
return list;
}
}
21. 递增顺序搜索树
/**
* 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 process(TreeNode x){
if(x==null)return null;
TreeNode left=process(x.left);
x.right=process(x.right);
x.left=null;
//找到left的尾部
if(left==null)return x;
TreeNode cur=left;
while(cur.right!=null){
cur=cur.right;
}
cur.right=x;
return left;
}
public TreeNode increasingBST(TreeNode root) {
return process(root);
}
}
22. BiNode
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode process(TreeNode x){
if(x==null)return null;
TreeNode leftHead=process(x.left);
x.left=null;
x.right=process(x.right);
TreeNode cur=leftHead;
if(cur==null)return x;
while(cur.right!=null){
cur=cur.right;
}
cur.right=x;
return leftHead;
}
public TreeNode convertBiNode(TreeNode root) {
return process(root);
}
}
23. 根据二叉树创建字符串
/**
* 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 {
String str="";
public void process(TreeNode x){
if(x==null){
str+=")";
return;
}
str+=x.val;
//左右子树全为null
if(x.left==null&&x.right==null){
return ;
}
//左右子树都不为null
if(x.left!=null&&x.right!=null){
str+="(";
process(x.left);
str+=")";
str+="(";
process(x.right);
str+=")";
return;
}
//左右子树有一个为null
if(x.left!=null){
str+="(";
process(x.left);
str+=")";
return;
}
if(x.right!=null){
str+="(";
//process(x.left);
str+=")";
str+="(";
process(x.right);
str+=")";
return;
}
}
public String tree2str(TreeNode root) {
if(root==null)return null;
process(root);
return str;
}
}
24. 将有序数组转换为二叉搜索树
/**
* 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 sortedArrayToBST(int[] nums) {
return process(nums,0,nums.length-1);
}
public TreeNode process(int[] nums,int left,int right){
if(left>right)return null;
int mid=left+((right-left)>>1);
TreeNode root=new TreeNode(nums[mid]);
root.left=process(nums,left,mid-1);
root.right=process(nums,mid+1,right);
return root;
}
}
25. 最小高度树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return process(nums,0,nums.length-1);
}
public TreeNode process(int[] nums,int left,int right){
if(left>right)return null;
int mid=left+((right-left)>>1);
TreeNode root=new TreeNode(nums[mid]);
root.left=process(nums,left,mid-1);
root.right=process(nums,mid+1,right);
return root;
}
}