Skip to content

Commit 1862154

Browse files
committed
update on 2020-05-10
1 parent 173a95b commit 1862154

16 files changed

+290
-109
lines changed

src/class08/Code05_MaxSubBSTHead.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public static Node maxSubBSTHead2(Node head) {
5656
return process(head).maxSubBSTHead;
5757
}
5858

59+
// 每一棵子树
5960
public static class Info {
6061
public Node maxSubBSTHead;
6162
public int maxSubBSTSize;
@@ -70,14 +71,14 @@ public Info(Node h, int size, int mi, int ma) {
7071
}
7172
}
7273

73-
public static Info process(Node head) {
74-
if (head == null) {
74+
public static Info process(Node X) {
75+
if (X == null) {
7576
return null;
7677
}
77-
Info leftInfo = process(head.left);
78-
Info rightInfo = process(head.right);
79-
int min = head.value;
80-
int max = head.value;
78+
Info leftInfo = process(X.left);
79+
Info rightInfo = process(X.right);
80+
int min = X.value;
81+
int max = X.value;
8182
Node maxSubBSTHead = null;
8283
int maxSubBSTSize = 0;
8384
if (leftInfo != null) {
@@ -94,9 +95,9 @@ public static Info process(Node head) {
9495
maxSubBSTSize = rightInfo.maxSubBSTSize;
9596
}
9697
}
97-
if ((leftInfo == null ? true : (leftInfo.maxSubBSTHead == head.left && leftInfo.max < head.value))
98-
&& (rightInfo == null ? true : (rightInfo.maxSubBSTHead == head.right && rightInfo.min > head.value))) {
99-
maxSubBSTHead = head;
98+
if ((leftInfo == null ? true : (leftInfo.maxSubBSTHead == X.left && leftInfo.max < X.value))
99+
&& (rightInfo == null ? true : (rightInfo.maxSubBSTHead == X.right && rightInfo.min > X.value))) {
100+
maxSubBSTHead = X;
100101
maxSubBSTSize = (leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
101102
+ (rightInfo == null ? 0 : rightInfo.maxSubBSTSize) + 1;
102103
}

src/class08/Code06_IsCBT.java

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ public static boolean isCBT1(Node head) {
3030
r = head.right;
3131
if (
3232
// 如果遇到了不双全的节点之后,又发现当前节点不是叶节点
33-
(leaf && !(l == null && r == null)) || (l == null && r != null)) {
33+
(leaf && (l != null || r != null)) || (l == null && r != null)
34+
35+
) {
3436
return false;
3537
}
3638
if (l != null) {
@@ -53,6 +55,7 @@ public static boolean isCBT2(Node head) {
5355
return process(head).isCBT;
5456
}
5557

58+
// 对每一棵子树,是否是满二叉树、是否是完全二叉树、高度
5659
public static class Info {
5760
public boolean isFull;
5861
public boolean isCBT;
@@ -65,28 +68,48 @@ public Info(boolean full, boolean cbt, int h) {
6568
}
6669
}
6770

68-
public static Info process(Node head) {
69-
if (head == null) {
71+
public static Info process(Node X) {
72+
if (X == null) {
7073
return new Info(true, true, 0);
7174
}
72-
Info leftInfo = process(head.left);
73-
Info rightInfo = process(head.right);
75+
Info leftInfo = process(X.left);
76+
Info rightInfo = process(X.right);
77+
78+
79+
7480
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
75-
boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height;
81+
82+
83+
boolean isFull = leftInfo.isFull
84+
&&
85+
rightInfo.isFull
86+
&& leftInfo.height == rightInfo.height;
87+
88+
7689
boolean isCBT = false;
7790
if (isFull) {
7891
isCBT = true;
79-
} else {
92+
} else { // 以x为头整棵树,不满
8093
if (leftInfo.isCBT && rightInfo.isCBT) {
81-
if (leftInfo.isCBT && rightInfo.isFull && leftInfo.height == rightInfo.height + 1) {
94+
95+
96+
if (leftInfo.isCBT
97+
&& rightInfo.isFull
98+
&& leftInfo.height == rightInfo.height + 1) {
8299
isCBT = true;
83100
}
84-
if (leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height + 1) {
101+
if (leftInfo.isFull
102+
&&
103+
rightInfo.isFull
104+
&& leftInfo.height == rightInfo.height + 1) {
85105
isCBT = true;
86106
}
87-
if (leftInfo.isFull && rightInfo.isCBT && leftInfo.height == rightInfo.height) {
107+
if (leftInfo.isFull
108+
&& rightInfo.isCBT && leftInfo.height == rightInfo.height) {
88109
isCBT = true;
89110
}
111+
112+
90113
}
91114
}
92115
return new Info(isFull, isCBT, height);

src/class08/Code07_lowestAncestor.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public static Node lowestAncestor1(Node head, Node o1, Node o2) {
2020
if (head == null) {
2121
return null;
2222
}
23+
// key的父节点是value
2324
HashMap<Node, Node> parentMap = new HashMap<>();
2425
parentMap.put(head, null);
2526
fillParentMap(head, parentMap);
@@ -52,6 +53,7 @@ public static Node lowestAncestor2(Node head, Node o1, Node o2) {
5253
return process(head, o1, o2).ans;
5354
}
5455

56+
// 任何子树,
5557
public static class Info {
5658
public Node ans;
5759
public boolean findO1;
@@ -64,15 +66,19 @@ public Info(Node a, boolean f1, boolean f2) {
6466
}
6567
}
6668

67-
public static Info process(Node head, Node o1, Node o2) {
68-
if (head == null) {
69+
public static Info process(Node X, Node o1, Node o2) {
70+
if (X == null) {
6971
return new Info(null, false, false);
7072
}
71-
Info leftInfo = process(head.left, o1, o2);
72-
Info rightInfo = process(head.right, o1, o2);
73-
74-
boolean findO1 = head == o1 || leftInfo.findO1 || rightInfo.findO1;
75-
boolean findO2 = head == o2 || leftInfo.findO2 || rightInfo.findO2;
73+
Info leftInfo = process(X.left, o1, o2);
74+
Info rightInfo = process(X.right, o1, o2);
75+
boolean findO1 = X == o1 || leftInfo.findO1 || rightInfo.findO1;
76+
boolean findO2 = X == o2 || leftInfo.findO2 || rightInfo.findO2;
77+
// O1和O2最初的交汇点在哪?
78+
// 1) 在左树上已经提前交汇了
79+
// 2) 在右树上已经提前交汇了
80+
// 3) 没有在左树或者右树上提前交汇,O1 O2 全了
81+
// 4)
7682
Node ans = null;
7783
if (leftInfo.ans != null) {
7884
ans = leftInfo.ans;
@@ -82,7 +88,7 @@ public static Info process(Node head, Node o1, Node o2) {
8288
}
8389
if (ans == null) {
8490
if (findO1 && findO2) {
85-
ans = head;
91+
ans = X;
8692
}
8793
}
8894
return new Info(ans, findO1, findO2);

src/class09/Code01_LowestLexicography.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@ public static String lowestString1(String[] strs) {
2323
return lowest;
2424
}
2525

26-
public static void process(String[] strs, HashSet<Integer> use, String path, ArrayList<String> all) {
26+
// strs里放着所有的字符串
27+
// 已经使用过的字符串的下标,在use里登记了,不要再使用了
28+
// 之前使用过的字符串,拼接成了-> path
29+
// 用all收集所有可能的拼接结果
30+
public static void process(String[] strs,
31+
HashSet<Integer> use,
32+
String path,
33+
ArrayList<String> all) {
2734
if (use.size() == strs.length) {
2835
all.add(path);
2936
} else {

src/class09/Code02_Light.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,23 @@ public static int minLight1(String road) {
1111
return process(road.toCharArray(), 0, new HashSet<>());
1212
}
1313

14+
// str[index....]位置,自由选择放灯还是不放灯
15+
// str[0..index-1]位置呢?已经做完决定了,那些放了灯的位置,存在lights里
16+
// 要求选出能照亮所有.的方案,并且在这些有效的方案中,返回最少需要几个灯
1417
public static int process(char[] str, int index, HashSet<Integer> lights) {
15-
if (index == str.length) {
18+
if (index == str.length) { // 结束的时候
1619
for (int i = 0; i < str.length; i++) {
17-
if (str[i] != 'X') {
18-
if (!lights.contains(i - 1) && !lights.contains(i) && !lights.contains(i + 1)) {
20+
if (str[i] != 'X') { // 当前位置是点的话
21+
if (!lights.contains(i - 1)
22+
&& !lights.contains(i)
23+
&& !lights.contains(i + 1)) {
1924
return Integer.MAX_VALUE;
2025
}
2126
}
2227
}
2328
return lights.size();
24-
} else {
29+
} else { // str还没结束
30+
// i X .
2531
int no = process(str, index + 1, lights);
2632
int yes = Integer.MAX_VALUE;
2733
if (str[index] == '.') {
@@ -40,7 +46,7 @@ public static int minLight2(String road) {
4046
while (index < str.length) {
4147
if (str[index] == 'X') {
4248
index++;
43-
} else {
49+
} else { // i -> .
4450
light++;
4551
if (index + 1 == str.length) {
4652
break;

src/class09/Code04_BestArrange.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,19 @@ public static int bestArrange1(Program[] programs) {
2222
return process(programs, 0, 0);
2323
}
2424

25+
// 还剩什么会议都放在programs里
26+
// done 之前已经安排了多少会议,数量
27+
// timeLine目前来到的时间点是什么
28+
29+
// 目前来到timeLine的时间点,已经安排了done多的会议,剩下的会议programs可以自由安排
30+
// 返回能安排的最多会议数量
2531
public static int process(Program[] programs, int done, int timeLine) {
2632
if (programs.length == 0) {
2733
return done;
2834
}
35+
// 还有会议可以选择
2936
int max = done;
37+
// 当前安排的会议是什么会,每一个都枚举
3038
for (int i = 0; i < programs.length; i++) {
3139
if (programs[i].start >= timeLine) {
3240
Program[] next = copyButExcept(programs, i);

src/class10/Code01_UnionFind.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ public static class UnionSet<V> {
2020
public HashMap<Node<V>, Integer> sizeMap;
2121

2222
public UnionSet(List<V> values) {
23-
for (V value : values) {
24-
Node<V> node = new Node<>(value);
25-
nodes.put(value, node);
23+
for (V cur : values) {
24+
Node<V> node = new Node<>(cur);
25+
nodes.put(cur, node);
2626
parents.put(node, node);
2727
sizeMap.put(node, 1);
2828
}
2929
}
3030

31+
// 从点cur开始,一直往上找,找到不能再往上的代表点,返回
3132
public Node<V> findFather(Node<V> cur) {
3233
Stack<Node<V>> path = new Stack<>();
3334
while (cur != parents.get(cur)) {
@@ -57,15 +58,11 @@ public void union(V a, V b) {
5758
if (aHead != bHead) {
5859
int aSetSize = sizeMap.get(aHead);
5960
int bSetSize = sizeMap.get(bHead);
60-
if (aSetSize >= bSetSize) {
61-
parents.put(bHead, aHead);
62-
sizeMap.put(aHead, aSetSize + bSetSize);
63-
sizeMap.remove(bHead);
64-
} else {
65-
parents.put(aHead, bHead);
66-
sizeMap.put(bHead, aSetSize + bSetSize);
67-
sizeMap.remove(aHead);
68-
}
61+
Node<V> big = aSetSize >= bSetSize ? aHead : bHead;
62+
Node<V> small = big == aHead ? bHead : aHead;
63+
parents.put(small, big);
64+
sizeMap.put(big, aSetSize + bSetSize);
65+
sizeMap.remove(small);
6966
}
7067
}
7168
}

src/class10/Code03_TopologySort.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ public static List<Node> sortedTopology(Graph graph) {
1313
// key:某一个node
1414
// value:剩余的入度
1515
HashMap<Node, Integer> inMap = new HashMap<>();
16-
// 入度为0的点,才能进这个队列
16+
// 剩余入度为0的点,才能进这个队列
1717
Queue<Node> zeroInQueue = new LinkedList<>();
18+
19+
1820
for (Node node : graph.nodes.values()) {
1921
inMap.put(node, node.in);
2022
if (node.in == 0) {

src/class10/Code04_Kruskal.java

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,16 @@
11
package class10;
22

3-
import java.util.ArrayList;
43
import java.util.Collection;
54
import java.util.Comparator;
65
import java.util.HashMap;
76
import java.util.HashSet;
8-
import java.util.List;
97
import java.util.PriorityQueue;
108
import java.util.Set;
119
import java.util.Stack;
1210

1311
//undirected graph only
1412
public class Code04_Kruskal {
15-
16-
public static class MySets{
17-
public HashMap<Node, List<Node>> setMap;
18-
public MySets(List<Node> nodes) {
19-
for(Node cur : nodes) {
20-
List<Node> set = new ArrayList<Node>();
21-
set.add(cur);
22-
setMap.put(cur, set);
23-
}
24-
}
25-
26-
27-
public boolean isSameSet(Node from, Node to) {
28-
List<Node> fromSet = setMap.get(from);
29-
List<Node> toSet = setMap.get(to);
30-
return fromSet == toSet;
31-
}
32-
33-
34-
public void union(Node from, Node to) {
35-
List<Node> fromSet = setMap.get(from);
36-
List<Node> toSet = setMap.get(to);
37-
for(Node toNode : toSet) {
38-
fromSet.add(toNode);
39-
setMap.put(toNode, fromSet);
40-
}
41-
}
42-
}
43-
44-
45-
46-
47-
48-
49-
50-
51-
52-
53-
54-
55-
13+
5614
// Union-Find Set
5715
public static class UnionFind {
5816
// key 某一个节点, value key节点往上的节点

src/class10/Code05_Prim.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,31 @@ public int compare(Edge o1, Edge o2) {
1919

2020
public static Set<Edge> primMST(Graph graph) {
2121
// 解锁的边进入小根堆
22-
PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(
23-
new EdgeComparator());
24-
HashSet<Node> set = new HashSet<>();
22+
PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());
23+
24+
// 哪些点被解锁出来了
25+
HashSet<Node> nodeSet = new HashSet<>();
2526
Set<Edge> result = new HashSet<>(); // 依次挑选的的边在result里
2627
for (Node node : graph.nodes.values()) { // 随便挑了一个点
2728
// node 是开始点
28-
if (!set.contains(node)) {
29-
set.add(node);
29+
if (!nodeSet.contains(node)) {
30+
nodeSet.add(node);
3031
for (Edge edge : node.edges) { // 由一个点,解锁所有相连的边
3132
priorityQueue.add(edge);
3233
}
3334
while (!priorityQueue.isEmpty()) {
3435
Edge edge = priorityQueue.poll(); // 弹出解锁的边中,最小的边
3536
Node toNode = edge.to; // 可能的一个新的点
36-
if (!set.contains(toNode)) { // 不含有的时候,就是新的点
37-
set.add(toNode);
37+
if (!nodeSet.contains(toNode)) { // 不含有的时候,就是新的点
38+
nodeSet.add(toNode);
3839
result.add(edge);
3940
for (Edge nextEdge : toNode.edges) {
4041
priorityQueue.add(nextEdge);
4142
}
4243
}
4344
}
4445
}
45-
//break;
46+
// break;
4647
}
4748
return result;
4849
}

0 commit comments

Comments
 (0)