树的常见算法题1

求中序遍历后继节点

1
2
3
4
5
6
7
8
9
10
class NextNode{
int value;
NextNode left;
NextNode right;
NextNode parent;

public NextNode(int value) {
this.value = value;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

public class FindNextNode {
//中序遍历 将节点加到list中
public static void findAllNextNode(NextNode node, List<NextNode> list){
if(node == null){
return;
}
if(node.left != null){
findAllNextNode(node.left,list);
}

list.add(node);

if(node.right != null){
findAllNextNode(node.right,list);
}
}

public static NextNode findNextNodeTest2(NextNode node){
//找到头节点
NextNode par = node;

while(par.parent != null){
par = par.parent;
}


List<NextNode> list = new ArrayList<>();

findAllNextNode(par,list);
System.out.println(list);

for (int i = 0; i < list.size() - 1; i++) {
if(list.get(i).equals(node)){
return list.get(i + 1);
}
}


return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//递归
public class FindNextNode {
public static NextNode findLeftNode(NextNode node){
if(node == null){
return null;
}

if(node.left == null){
return node;
}

return findLeftNode(node.left);
}


public static NextNode findNextNodeTest(NextNode node){
if(node.right != null){
return findLeftNode(node.right);
}

NextNode parentNode = node.parent;

while(parentNode != null && parentNode.right ==node){
node = parentNode;
parentNode = node.parent;
}
return parentNode;
}

}

判断平衡二叉树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class ACLTest {

//每一次递归传递的信息
static class MSG{
int height;
boolean isAVLTree;

public MSG() {
}

public MSG(int height, boolean isAVLTree) {
this.height = height;
this.isAVLTree = isAVLTree;
}

get()...
set()...
}


public static MSG isAVL(Node head){
if(head == null){
return new MSG(0, true);
}

MSG msgLeft = isAVL(head.left);
MSG msgRight = isAVL(head.right);

MSG msg = new MSG();

//求出树的高度
msg.height = Math.max(msgLeft.height,msgRight.height) + 1;
//判断是否是平衡二叉树
msg.isAVLTree = msgLeft.isAVLTree && msgRight.isAVLTree && (Math.abs(msgLeft.height - msgRight.height) <= 1);

return msg;
}


public static boolean isAVLTest(Node head){
MSG avl = isAVL(head);
return avl.isAVLTree;
}
}

派对的最大快乐值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

/***
* 公司的人员结构可以看作是一颗标准的没有环的多叉树,树的肉头点是唯一的老板,
* 除老板外每个员工的都有唯一的直接上级。
* 叶节点是没有任何我下属的基层员工,
* 除基层员工外,每个员工都有一个或多个直接下级
*/


/***
* 派对的最大快乐值,你可以决定哪些员工来,哪些员工不来,规则
*
* 1.如果某个员工来了,那么这个员工的所有直接下级都不能来,
* 2.派对的整体快乐值是所有到场员工快乐值的累加
* 3.你的目标的是让派对的整体的快乐值尽量大
*
* 给定一颗多叉树的头节点boss 请返回派对的最大快乐值
*
*/

class Employee{
//这个员工的快乐值
public int happy;
//下属
List<Employee> subordinates;

public Employee(int happy) {
this.happy = happy;
}
}

public class MaxHappy{

//每一次递归返回的信息
static class Info{
//头节点来时最大快乐值
public int withHead;
//头节点不来是最大快乐值
public int withOutHead;
}

public static Info process(Employee e){
//如果是基层员工
//返回一个Info 第一个参数,如果这个员工参加的快乐值,如果这个员工不参加的快乐值为0
if(e.subordinates == null){
return new Info(e.happy,0);
}

//如果不是基层员工
//定义两个变量 。如果这个员工参加 或者这个员工不参加

//如果参加需要先加上这位员工的快乐值
int withHeadHappy = e.happy;
int withOutHeadHappy = 0;

//对这位员工的直接下层进行循环访问
for(Employee next : e.subordinates){
//得到下属的信息
Info nextInfo = process(next);
//如果这位员工参加,那么它的直接下属不能参加,所以于下属的withOutHead相加
withHeadHappy += nextInfo.withOutHead;
///如果这位员工不参加,那么它的直接下属可以参加,所以于下属的withHead相加
withOutHeadHappy += Math.max(nextInfo.withHead,nextInfo.withOutHead);
}
//返回这个员工参加或不参加有的快乐值
return new Info(withHeadHappy,withOutHeadHappy);
}

public static int MaxHappyTest(Employee employee){
Info process = process(employee);
return process.withOutHead > process.withHead ? process.withOutHead : process.withHead;
}
}

返回整颗二叉树的最大距离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class MaxDistance {

static class Info{
//最大距离
public int MaxDistance;
//树的高度
public int height;

public Info(int maxDistance, int hight) {
MaxDistance = maxDistance;
this.height = hight;
}

}


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 height = Math.max(leftInfo.height,rightInfo.height) + 1;

int maxDistance = Math.max(Math.max(leftInfo.MaxDistance,rightInfo.MaxDistance)
,rightInfo.height + leftInfo.height + 1);

return new Info(maxDistance,height);
}

public static int MaxDistanceTest(Node head){
return process(head).MaxDistance;
}


}

求两个节点最近的父节点

  • 方法一 HashMap + HashSet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public static void findAll(Node head, Map<Node,Node> map){
if(head == null){
return;
}
if(head.left != null){
map.put(head.left,head);
findAll(head.left,map);
}

if(head.right != null){
map.put(head.right,head);
findAll(head.right,map);
}

}

public static Node RecentlyFatherTest(Node head,Node node1,Node node2){
HashMap<Node, Node> map = new HashMap<>();
map.put(head,null);
findAll(head,map);

HashSet<Node> set = new HashSet<>();
set.add(node1);
while(true){
if (map.get(node1) == null){
break;
}
set.add(map.get(node1));
node1 = map.get(node1);
}

while(true){
if( set.contains(node2) ){
break;
}

node2 = map.get(node2);
}
return node2;
}
  • 方法二 递归
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//每一次递归返回的信息
static class Info{
public Node ans;
public boolean findNode1;
public boolean findNode2;

public Info(Node ans, boolean findNode1, boolean findNode2) {
this.ans = ans;
this.findNode1 = findNode1;
this.findNode2 = findNode2;
}
}


public static Info RF(Node head,Node node1,Node node2){
if(head == null){
return new Info(null,false,false);
}

Info leftInfo = RF(head.left,node1,node2);
Info rightInfo = RF(head.right,node1,node2);


boolean findNode1 = head == node1 || leftInfo.findNode1 || rightInfo.findNode1;
boolean findNode2 = head == node2 || leftInfo.findNode2 || rightInfo.findNode2;

Node ans = null;
if(leftInfo.ans != null){
ans = leftInfo.ans;
}
if (rightInfo.ans != null){
ans = rightInfo.ans;
}
if(ans == null){
if(findNode1 && findNode2){
ans = head;
}
}

return new Info(ans,findNode1,findNode2);
}

public static Node RecentlyFatherTest2(Node head,Node node1,Node node2){
Info info = RF(head, node1, node2);

System.out.println(info.ans);
return info.ans;
}

树的常见算法题1
https://johnjoyjzw.github.io/2020/01/06/树常见算法题1/
Author
John Joy
Posted on
January 6, 2020
Licensed under