Skip to content

Commit 2bdb0f4

Browse files
committed
update
1 parent c0e5773 commit 2bdb0f4

File tree

4 files changed

+285
-0
lines changed

4 files changed

+285
-0
lines changed

0207-课程表.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# 课程表
2+
3+
## 题目描述
4+
5+
现在你总共有 n 门课需要选,记为 0 到 n-1。
6+
7+
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]
8+
9+
给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?
10+
11+
```
12+
输入: 2, [[1,0]]
13+
输出: true
14+
解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。
15+
16+
输入: 2, [[1,0],[0,1]]
17+
输出: false
18+
解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。
19+
```
20+
21+
你可以假定输入的先决条件中没有重复的边。
22+
23+
## 分析
24+
25+
使用一个队列保存入度为0的结点。然后将队列元素弹出,遍历给定数组,找到由该元素可到达的另一个元素。判断到达元素入度是否为0,若是,将其进入队列。
26+
27+
## 算法
28+
29+
```java
30+
class Solution {
31+
public boolean canFinish(int numCourses, int[][] prerequisites) {
32+
int[] inDegree = new int[numCourses];
33+
for (int i = 0; i < prerequisites.length; i++) {
34+
inDegree[prerequisites[i][0]]++;
35+
}
36+
37+
Queue<Integer> queue = new LinkedList<>();
38+
for(int i = 0; i < inDegree.length; i++){
39+
if(inDegree[i] == 0)
40+
queue.offer(i);
41+
}
42+
43+
int count = 0;
44+
while(!queue.isEmpty()){
45+
int num = queue.poll();
46+
count++;
47+
for (int[] p : prerequisites) {
48+
if (p[1] == num) {
49+
inDegree[p[0]]--;
50+
if (inDegree[p[0]] == 0)
51+
queue.offer(p[0]);
52+
}
53+
}
54+
}
55+
return count == numCourses;
56+
}
57+
}
58+
```

0210-课程表 II.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# 课程表 II
2+
3+
## 题目描述
4+
5+
现在你总共有 n 门课需要选,记为 0 到 n-1。
6+
7+
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]
8+
9+
给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。
10+
11+
可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。
12+
13+
```
14+
输入: 2, [[1,0]]
15+
输出: [0,1]
16+
解释: 总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。
17+
18+
输入: 4, [[1,0],[2,0],[3,1],[3,2]]
19+
输出: [0,1,2,3] or [0,2,1,3]
20+
解释: 总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。
21+
因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3] 。
22+
```
23+
24+
你可以假定输入的先决条件中没有重复的边
25+
26+
## 分析
27+
28+
使用一个队列保存入度为0的结点。然后将队列元素弹出,遍历给定数组,找到由该元素可到达的另一个元素。判断到达元素入度是否为0,若是,将其进入队列。
29+
30+
在出队列的时候,保存结果即可。
31+
32+
## 算法
33+
34+
```java
35+
class Solution {
36+
public int[] findOrder(int numCourses, int[][] prerequisites) {
37+
int[] inDegree = new int[numCourses];
38+
for (int i = 0; i < prerequisites.length; i++) {
39+
inDegree[prerequisites[i][0]]++;
40+
}
41+
42+
Queue<Integer> queue = new LinkedList<>();
43+
for(int i = 0; i < inDegree.length; i++){
44+
if(inDegree[i] == 0)
45+
queue.offer(i);
46+
}
47+
int[] result = new int[numCourses];
48+
int count = 0;
49+
while(!queue.isEmpty()){
50+
int num = queue.poll();
51+
result[count++] = num;
52+
for (int[] p : prerequisites) {
53+
if (p[1] == num) {
54+
inDegree[p[0]]--;
55+
if (inDegree[p[0]] == 0)
56+
queue.offer(p[0]);
57+
}
58+
}
59+
}
60+
return count == numCourses ? result : new int[0];
61+
}
62+
}
63+
64+
```

0399-除法求值.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# 除法求值
2+
3+
## 题目描述
4+
5+
给出方程式 `A / B = k`, 其中 `A``B` 均为代表字符串的变量, `k` 是一个浮点型数字。根据已知方程式求解问题,并返回计算结果。如果结果不存在,则返回 `-1.0`
6+
7+
示例 :
8+
给定 `a / b = 2.0,` `b / c = 3.0`
9+
问题: `a / c = ?`, `b / a = ?`, `a / e = ?`, `a / a = ?`, `x / x = ?`
10+
返回 `[6.0, 0.5, -1.0, 1.0, -1.0 ]`
11+
12+
基于上述例子,输入如下
13+
14+
```
15+
equations(方程式) = [ ["a", "b"], ["b", "c"] ],
16+
values(方程式结果) = [2.0, 3.0],
17+
queries(问题方程式) = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ].
18+
```
19+
20+
输入总是有效的。你可以假设除法运算中不会出现除数为0的情况,且不存在任何矛盾的结果
21+
22+
## 分析
23+
24+
并查集。
25+
26+
详解请见 [详解](https://www.bilibili.com/video/av40929397?from=search&seid=5462235911348002192)
27+
28+
## 算法
29+
30+
```java
31+
32+
class Solution {
33+
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
34+
Map<String, Node> map = new HashMap<>();
35+
36+
for(int i = 0; i < values.length; i++){
37+
List<String> list = equations.get(i);
38+
39+
Node node1 = null, node2 = null;
40+
if((node1 = map.get(list.get(0))) == null){
41+
node1 = new Node(values[i]);
42+
map.put(list.get(0), node1);
43+
}
44+
45+
if((node2 = map.get(list.get(1))) == null){
46+
node2 = new Node();
47+
map.put(list.get(1), node2);
48+
}
49+
50+
Node.union(node1, node2, values[i], map);
51+
}
52+
53+
double[] result = new double[queries.size()];
54+
55+
for(int i = 0; i < result.length; i++){
56+
List<String> list = queries.get(i);
57+
58+
Node node1, node2;
59+
if((node1 = map.get(list.get(0))) != null && (node2 = map.get(list.get(1))) != null && Node.find(node1) == Node.find(node2)){
60+
result[i] = node1.value / node2.value;
61+
}else{
62+
result[i] = -1.0;
63+
}
64+
}
65+
return result;
66+
}
67+
}
68+
69+
class Node{
70+
public double value;
71+
public Node parent;
72+
73+
public Node(){
74+
this(1.0);
75+
}
76+
77+
public Node(double v){
78+
value = v;
79+
parent = this;
80+
}
81+
82+
public static Node find(Node node){
83+
while(node != node.parent){
84+
node = node.parent;
85+
}
86+
return node;
87+
}
88+
89+
public static void union(Node a, Node b, double num, Map<String, Node> map){
90+
Node f1 = find(a);
91+
Node f2 = find(b);
92+
93+
double ratio = b.value * num / a.value;
94+
95+
for(Node node : map.values()){
96+
if(find(node) == f1)
97+
node.value *= ratio;
98+
}
99+
f1.parent = f2;
100+
}
101+
}
102+
```

0841-钥匙和房间.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# 钥匙和房间
2+
3+
## 题目描述
4+
5+
`N` 个房间,开始时你位于 `0` 号房间。每个房间有不同的号码:`0,1,2,...,N-1`,并且房间里可能有一些钥匙能使你进入下一个房间。
6+
7+
在形式上,对于每个房间 `i` 都有一个钥匙列表 `rooms[i]`,每个钥匙 `rooms[i][j]``[0,1,...,N-1]` 中的一个整数表示,其中 `N = rooms.length`。 钥匙 `rooms[i][j] = v` 可以打开编号为 `v` 的房间。
8+
9+
最初,除 `0` 号房间外的其余所有房间都被锁住。
10+
11+
你可以自由地在房间之间来回走动。
12+
13+
如果能进入每个房间返回 `true`,否则返回 `false`
14+
15+
```
16+
输入: [[1],[2],[3],[]]
17+
输出: true
18+
解释:
19+
我们从 0 号房间开始,拿到钥匙 1。
20+
之后我们去 1 号房间,拿到钥匙 2。
21+
然后我们去 2 号房间,拿到钥匙 3。
22+
最后我们去了 3 号房间。
23+
由于我们能够进入每个房间,我们返回 true。
24+
25+
输入:[[1,3],[3,0,1],[2],[0]]
26+
输出:false
27+
解释:我们不能进入 2 号房间。
28+
```
29+
30+
1. 1 <= rooms.length <= 1000
31+
2. 0 <= rooms[i].length <= 1000
32+
3. 所有房间中的钥匙数量总计不超过 3000。
33+
34+
## 分析
35+
36+
广度优先搜索。使用一个队列保存每个房间的钥匙,然后依次去开房间,直到队列为空为止。
37+
38+
## 算法
39+
40+
```java
41+
class Solution {
42+
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
43+
boolean[] visited = new boolean[rooms.size()];
44+
int count = 1;
45+
visited[0] = true;
46+
Queue<Integer> queue = new LinkedList<>(rooms.get(0));
47+
48+
while(!queue.isEmpty()){
49+
int room = queue.poll();
50+
if(!visited[room]){
51+
for(Integer i : rooms.get(room)){
52+
queue.offer(i);
53+
}
54+
count++;
55+
visited[room] = true;
56+
}
57+
}
58+
return count == rooms.size();
59+
}
60+
}
61+
```

0 commit comments

Comments
 (0)