将一颗二叉树按层经行遍历(宽度优先遍历)
- 思路:
- 首先头节点进队列,然后弹出并打印,记录当前的节点 node
- 然后判断 node 的左孩子是否存在,若存在进队列,然后判断node的右孩子是否存在,若存在右孩子进队列 .... 依次循环
- 结束条件 该队列为空结束
- coding
public static void widthOrder(TreeNode head){
if (head == null){
return;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(head);
while (!queue.isEmpty()){
TreeNode node = queue.poll();
System.out.print(node.val + " ");
if (node.left!=null)
queue.add(node.left);
if (node.right!=null)
queue.add(node.right);
}
}
统计二叉树中那一层的节点数量最多
- 思路一
-
1、使用一张Hash表来保存每一个节点所在的层数
-
2、创建一个Hash表,将头节点反倒这个Hash表中,创建一个队列,头节点入队列,创建几个变量 currentLevel统计当前在那一层,levelNodes统计当前层的节点数量 , max 每层节点的最多的个数
-
3、队列不为空,弹出头节点,如果头节点的左右孩子不为空,左右孩子记录在hashMap中,并且左右孩子入队列,如果当前节点所在的层和currentLevel相同证明实在同一层,那么这层节点的数量要 ++
-
4、如果当前的层数和currentLevel不同,证明现在已经不是同一层了,让levelNodes也就是当前层的节点个数和max比较,决策出来一个较大的给max,同时levelNodes = 1 当前层也++ currentLevel++。
- coding
public static Integer widthMaxNodes(TreeNode head){
if (head == null){
return 0;
}
//用来记录当前节点在那一层
Map<TreeNode,Integer> levelMap = new HashMap<>();
levelMap.put(head,1);
Queue<TreeNode> queue = new LinkedList<>();
queue.add(head);
//统计当前层数
Integer currentLevel = 1;
//当前层的节点数量
Integer levelNodes = 1;
Integer max = 0;
while(!queue.isEmpty()){
TreeNode node = queue.poll();
Integer curNodeLevel = levelMap.get(node);
if (node.left!=null){
levelMap.put(node.left,currentLevel + 1);
queue.add(node.left);
}
if (node.right!=null){
levelMap.put(node.right,currentLevel + 1);
queue.add(node.right);
}
if (curNodeLevel == currentLevel){
levelNodes++;
}else{
max = Math.max(max,levelNodes);
currentLevel++;
levelNodes = 1;
}
}
return Math.max(max,levelNodes);
}
- 思路二
- 1、 首先准备一个队列 queue ,头节点入队列 和两个变量curEnd 和 nextEnd , 还有一个变量curLevelNodes记录当前层的节点个数,一个max变量,用来决策哪一个层的节点的个数最多
- 2、队列不为空首先弹出来队列里的那一个元素记作cur,如果cur的左节点不为空,左节点入队列并且nextEnd指向cur.left。cur的右节点也是同理,当前节点数量 ++ 也就是 curLevelNodes++
- 3、如果当前节点和 和 curEnd是同一个,证明这同一层已经统计玩了,这个时候需要决策出来max,curLevelNodes = 0,将nextEnd赋值给curEnd curEnd = nextEnd;
- coding
public static int maxWidthNoMap(TreeNode head){
if (head==null){
return 0;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(head);
TreeNode curEnd = head; //当前层的最右边的节点
TreeNode nextEnd = null; //下一层的最右边的节点
int curLevelNodes = 0; //当前层节点的个数
int max = 0; //
while(!queue.isEmpty()){
TreeNode cur = queue.poll();
if (cur.left!=null){
queue.add(cur.left);
nextEnd = cur.left;
}
if (cur.right!=null){
queue.add(cur.right);
nextEnd = cur.right;
}
curLevelNodes++;
if (cur == curEnd){
max = Math.max(max,curLevelNodes);
curLevelNodes = 0;
curEnd = nextEnd;
}
}
return max;
}
序列化一颗二叉树
二叉树的递归套路
判断一棵树是否是平衡二叉树
- 思路:
- 1、假设以x开头为头节点,然后分别给我的左子树要信息,给我的右子树要信息
- 2、左树要平衡,右树要平衡,并且左树和右树的高度不超过 1
- coding
- 需要的信息
private static class ReturnInfo{
boolean isBalance;
int height;
public ReturnInfo(boolean isBalance, int height) {
this.isBalance = isBalance;
this.height = height;
}
}
private static ReturnInfo isBalance(TreeNode head){
if (head == null){
return new ReturnInfo(true,0);
}
ReturnInfo leftInfo = isBalance(head.left);
ReturnInfo rightInfo = isBalance(head.right);
int height = Math.max(leftInfo.height,rightInfo.height ) + 1;
boolean isBalacne = true;
if (!leftInfo.isBalance || !rightInfo.isBalance || Math.abs(leftInfo.height - rightInfo.height)>1){
isBalacne = false;
}
return new ReturnInfo(isBalacne,height);
}
求二叉树两个节点的最大距离
- 思路
- 同样分成两种情况,过x节点 或者 不过x节点
- 过X节点,左子树的深度 + 右子树的深度 + 1
- 不过X节点,左子树的最远距离 或者是右子树的最远距离
- coding
- 需要的信息
private static class ReturnInfo{
int maxDeep;
int height;
public ReturnInfo(int maxDeep, int height) {
this.maxDeep = maxDeep;
this.height = height;
}
}
public static ReturnInfo maxDistance(TreeNode head){
if (head == null){
return new ReturnInfo(0,0);
}
ReturnInfo leftInfo = maxDistance(head.left);
ReturnInfo rightInfo = maxDistance(head.right);
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
int distance = Math.max(Math.max(leftInfo.maxDeep, rightInfo.maxDeep), leftInfo.height+ rightInfo.height +1);
return new ReturnInfo(distance,height);
}
给定一个头节点head 返回这棵树中最大的二叉搜索子树的个数
- 思路
- coding
private static class ReturnInfo{
boolean isbst;
int maxSubBSTSize;
int min;
int max;
public ReturnInfo(boolean isbst, int maxSubBSTSize, int min, int max) {
this.isbst = isbst;
this.maxSubBSTSize = maxSubBSTSize;
this.min = min;
this.max = max;
}
}
public static ReturnInfo process(TreeNode head){
if (head == null){
return null;
}
ReturnInfo leftInfo = process(head.left);
ReturnInfo rightInfo = process(head.right);
int min = head.val;
int max = head.val;
if (leftInfo!=null){
min = Math.min(min,leftInfo.min);
max = Math.max(max,leftInfo.max);
}
if (rightInfo!=null){
min = Math.min(min,rightInfo.min);
max = Math.max(max,rightInfo.max);
}
int maxSubBSTSize = 0;
if (leftInfo!=null){
maxSubBSTSize = leftInfo.maxSubBSTSize;
}
if (rightInfo!=null){
maxSubBSTSize = Math.max(maxSubBSTSize, rightInfo.maxSubBSTSize);
}
boolean isAllbst = false;
if (
(leftInfo == null?true:leftInfo.isbst)
&&
(rightInfo == null?true:rightInfo.isbst)
&&
(leftInfo == null?true:leftInfo.max < head.val)
&&
(rightInfo == null?true:rightInfo.min > head.val)
){
maxSubBSTSize =
(leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
+
(rightInfo == null? 0 : rightInfo.maxSubBSTSize)+1;
isAllbst = true;
}
return new ReturnInfo(isAllbst,maxSubBSTSize,min,max);
}
party的最大快乐值
- 思路:分成两种情况去考虑
- 1、情况一:在节点来的情况下,x节点来那么x下面的a,b,c就不能来,所以他的最大快乐值为 x.val + a不来的最大快乐 + b不来的最大快乐 + c不来的最大快乐
- 2、情况二:在节点x不来的情况下 a,b,c 节点可以决定来不来,此时的最大快乐值为Math.max(a来的最大快乐,a不来的最大快乐) + Math.max(b来的最大快乐,b不来的最大快乐) + Math.max(c来的最大快乐,c不来的最大快乐) + 0
//要返回的信息
public static class ReturnInfo{
public int laiMaxHappy;
public int buMaxHappy;
public ReturnInfo(){}
public ReturnInfo(int laiMaxHappy, int buMaxHappy) {
this.laiMaxHappy = laiMaxHappy;
this.buMaxHappy = buMaxHappy;
}
}
public static ReturnInfo process(Employee x){
if (x.nexts.isEmpty()){
return new ReturnInfo(x.happy,0);
}
int lai = x.happy; // x 来的情况下,整棵树的最大收益
int bu = 0; // x 不来的情况下,整棵树的最大收益
for (Employee next:x.nexts){
ReturnInfo nextInfo = process(next);
lai += nextInfo.buMaxHappy;
bu += Math.max(nextInfo.laiMaxHappy,nextInfo.buMaxHappy);
}
return new ReturnInfo(lai,bu);
}
持续更新中 ------------------