Skip to content

Commit c3f6d32

Browse files
committed
fix some bugs
1 parent 0eb9a70 commit c3f6d32

File tree

14 files changed

+102
-32
lines changed

14 files changed

+102
-32
lines changed

1_Divide_and_Conquer/readme.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ $$
169169
在平均情况下,我们选择的一般不是最好也不是最差。和快速排序的平均复杂度证明类似,本算法也可以证明平均复杂度为O(n)
170170

171171
## Problem 3.
172-
> Consider an n-node complete binary tree T, where n = 2^d^ − 1 for some d. Each node v of T is labeled with a real number xv. You may assume that the real numbers labeling the nodes are all distinct. A node v of T is a local minimum if the label x~v~ is less than the label x~w~ for all nodes w that are joined to v by an edge.
172+
> Consider an n-node complete binary tree T, where n = 2^d^ − 1 for some d. Each node v of T is labeled with a real number x~v~. You may assume that the real numbers labeling the nodes are all distinct. A node v of T is a local minimum if the label x~v~ is less than the label x~w~ for all nodes w that are joined to v by an edge.
173173
> You are given such a complete binary tree T, but the labeling is only specified in the following implicit way: for each node v, you can determine the value x~v~ by probing the node v. Show how to find a local minimum of T using only O(logn) probes to the nodes of T.
174174
175175
### 思路与代码
@@ -368,7 +368,7 @@ $$
368368
$$
369369
min(rocks[i] - rocks[i-1] , i ∈ [1,N + 1]) < = d <= L
370370
$$
371-
因此,我们可以用二分的方法猜测该最小距离。设当前的范围[left,right)。 每次我们查看 left 和 right的中点mid,该mid就是我们猜测的最小的距离的最大值,然后对rocks中,间距不大于mid的进行计数(这些就是要删除的点),记为cnt。
371+
因此,我们可以用二分的方法猜测该最小距离。设当前的范围[left,right)。 每次我们查看 left 和 right的中点mid,该mid就是我们猜测的最小的距离的最大值,然后对rocks中,间距**不大于**mid的进行计数(这些就是要删除的点),记为cnt。
372372

373373
- cnt > M: 说明该mid值太大了,需要减小,区间变为 [left,mid)
374374
- cnt < M: 说明mid太小,区间变为 [mid+1,right)
@@ -399,7 +399,7 @@ def solve_largest_minimum_spacing(L, M, N, rocks):
399399
rocks = [0] + rocks + [L]
400400
N += 2
401401
rocks.sort()
402-
left = min(rocks[i] - rocks[i - 1] for i in range(1, N))
402+
left = min(rocks[i] - rocks[i - 1] for i in range(1, N)) # left start with 0 is ok.
403403
return binary_search(left, L + 1, rocks, M, N)
404404

405405
# solve_largest_minimum_spacing(L, M, N, rocks)
@@ -430,7 +430,7 @@ def solve_largest_minimum_spacing(L, M, N, rocks):
430430
## Problem 6.
431431

432432
> Recall the problem of finding the number of inversions. As in the course, we are given a sequence of n numbers a1,··· ,an, which we assume are all distinct, and we difine an inversion to be a pair i < j such that ai > aj.
433-
> We motivated the problem of counting inversions as a good measure of how different two orderings are. However, one might feel that this measure is too sensitive. Let’s call a pair a significant inversion if i < j and ai > 3aj. Given an O(nlogn) algorithm to count the number of significant inversions between two orderings.
433+
> We motivated the problem of counting inversions as a good measure of how different two orderings are. However, one might feel that this measure is too sensitive. Let’s call a pair a significant inversion if i < j and ai > 3a~j~. Given an O(nlogn) algorithm to count the number of significant inversions between two orderings.
434434
435435
### 思路与代码
436436

2_DP/5.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
import collections
55

66

7-
def can_cross(stones):
7+
def can_cross2(stones):
88
n = len(stones)
99
val2id = {stone: i for i, stone in enumerate(stones)}
10-
dp = collections.defaultdict(lambda :collections.defaultdict(int))
10+
dp = collections.defaultdict(lambda: collections.defaultdict(int))
1111
dp[1][0] = True
1212
for j in range(1, n):
13-
for i in dp[j]: # the same as dp[j].keys()
13+
for i in dp[j]: # the same as dp[j].keys()
1414
step = stones[j] - stones[i]
1515
for k in [step + 1, step, step - 1]:
1616
_next = stones[j] + k
@@ -23,6 +23,17 @@ def can_cross(stones):
2323
return False
2424

2525

26+
def can_cross(stones):
27+
dp = {stone: {} for stone in stones}
28+
dp[0][0] = 0
29+
for stone in stones:
30+
for step in dp[stone].values():
31+
for k in [step + 1, step, step - 1]:
32+
if k > 0 and stone + k in dp:
33+
dp[stone + k][stone] = k
34+
return len(dp[stones[-1]].keys()) > 0
35+
36+
2637
if __name__ == '__main__':
2738
print(can_cross([0, 2]))
2839
print(can_cross([0, 1, 3, 5, 6, 8, 12, 17]))

2_DP/readme.md

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def rob_circle2(nums):
136136

137137
该题正确性的证明在于对状态转移方程的正确性证明。
138138

139-
对于i不抢,显然只能为dp[i-2],而抢显然为dp[i-2] + nums[i],因此我们只需要取其最大值即可。
139+
对于i不抢,显然只能为dp[i-1],而抢显然为dp[i-2] + nums[i],因此我们只需要取其最大值即可。
140140

141141
环形情况同理。
142142

@@ -151,10 +151,8 @@ def rob_circle2(nums):
151151

152152
## 3. Partition
153153

154-
> Given a string s, partition s such that every substring of the partition is a palindrome. Return
155-
> the minimum cuts needed for a palindrome partitioning of s.
156-
> For example, given s = “aab", return 1 since the palindrome partitioning ["aa", "b"] could
157-
> be produced using 1 cut.
154+
> Given a string s, partition s such that every substring of the partition is a palindrome. Return the minimum cuts needed for a palindrome partitioning of s.
155+
> For example, given s = “aab", return 1 since the palindrome partitioning ["aa", "b"] could be produced using 1 cut.
158156
159157
### 问题分析(最优子结构及DP表达式)
160158

@@ -282,7 +280,7 @@ def decoding_ways(s):
282280

283281
> A frog is crossing a river. The river is divided into x units and at each unit there may or may not exist a stone. The frog can jump on a stone, but it must not jump into the water.
284282
>
285-
> If the frog’s last jump was k units, then its next jump must be either k −1,k, or k +1 units. Note that the frog can only jump in the forward direction.
283+
> If the frog’s last jump was k units, then its next jump must be either k −1, k, or k +1 units. Note that the frog can only jump in the forward direction.
286284
>
287285
> Given a list of stones’ positions (in units) in sorted ascending order, determine if the frog is able to cross the river by landing on the last stone. Initially, the frog is on the first stone and assume the first jump must be 1 unit.
288286
@@ -292,9 +290,27 @@ def decoding_ways(s):
292290

293291
因此对于到达了某一个点,我们可以查看其上一次是从哪个点跳过来的。
294292

293+
设dp[ j ]\[ i ] 为从i到达j 的步数,初始时把所有的石头存放进hash表。然后设置dp\[0][0] = 0. 接着对于每个石头,从可以到达该石头的所有石头中取出步数k(k > 0),然后当前的stone + k看其是否是合法的石头,是的话就有d\[stone + k ][stone] = k
294+
295+
```
296+
def can_cross(stones):
297+
dp = {stone: {} for stone in stones}
298+
dp[0][0] = 0
299+
for stone in stones:
300+
for step in dp[stone].values():
301+
for k in [step + 1, step, step - 1]:
302+
if k > 0 and stone + k in dp:
303+
dp[stone + k][stone] = k
304+
return len(dp[stones[-1]].keys()) > 0
305+
```
306+
307+
308+
309+
### 原来的方法
310+
295311
设dp[ j ]\[ i ] 从i可以到达j,因此,对于点 j,我们只需要查看可以从哪个地方跳转过来(这里假设为i),然后查看其跳跃的距离$step = stones[j] - stones[i]$ , 则下一次的跳的距离为$step + 1, step, step - 1$ ,然后查看下一个点\_id存不存在(用Hash),存在将dp\[\_id][j] 设置为可达 ,若$\_id==n-1$,说明到达了对岸。这样复杂度为O(n^2^)
296312

297-
### 代码
313+
#### 代码
298314

299315
在具体的实现上,使用了类似邻接表的方式来加快速度。
300316

2_DP/readme.pdf

151 KB
Binary file not shown.

3_Greedy/1.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ def can_be_a_graph(degrees):
77
d_sum, n = sum(degrees), len(degrees)
88
if d_sum & 1 or n * (n - 1) < d_sum or max(degrees) > n - 1: return False
99
for n in range(n, -1, -1):
10-
degrees.sort(reverse=True) # 可以每一次算完类似合并排序合并过程使得总复杂度为O(n^2)
10+
degrees.sort(reverse=True) # 可以每一次算完类似合并排序合并过程使得总复杂度为O(n^2)
1111
for i in range(1, n):
1212
if degrees[0] <= 0: break
1313
degrees[i] -= 1
@@ -17,6 +17,44 @@ def can_be_a_graph(degrees):
1717
return True
1818

1919

20+
def merge(a, ls, le, re):
21+
t = []
22+
_ls = ls
23+
rs = le
24+
while ls < le and rs < re:
25+
if a[ls] >= a[rs]:
26+
t.append(a[ls])
27+
ls += 1
28+
else:
29+
t.append(a[rs])
30+
rs += 1
31+
for i in range(ls, le):
32+
t.append(a[i])
33+
for i in range(rs, re):
34+
t.append(a[i])
35+
36+
for i in range(_ls, re):
37+
a[i] = t[i - _ls]
38+
39+
40+
def can_be_a_graph2(degrees):
41+
d_sum, n = sum(degrees), len(degrees)
42+
if d_sum & 1 or n * (n - 1) < d_sum or max(degrees) > n - 1: return False
43+
degrees.sort(reverse=True)
44+
while degrees:
45+
k = degrees[0]
46+
for i in range(1, n):
47+
if degrees[0] <= 0: break
48+
degrees[i] -= 1
49+
if degrees[i] < 0: return False
50+
degrees[0] -= 1
51+
if degrees[0] != 0: return False
52+
n -= 1
53+
degrees.pop(0)
54+
merge(degrees, 0, k, n)
55+
return True
56+
57+
2058
if __name__ == '__main__':
2159
test_case = [
2260
[1, 1, 2, 2, 4], # True
@@ -29,4 +67,4 @@ def can_be_a_graph(degrees):
2967
]
3068

3169
for t in test_case:
32-
print(can_be_a_graph(t[:]))
70+
print(can_be_a_graph(t[:]) , can_be_a_graph2(t[:]))

3_Greedy/readme.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
首先,判断满足如下条件:
2525

2626
- 度数和为偶数 (对于无向图,每条边贡献两个度,因此度数和必为偶数)
27-
- 总边数不超过 $ \frac{n*(n-1)}{2} $ 在(完全的简单图,最大度不超过n-1)
27+
- 总边数不超过 $ \frac{n*(n-1)}{2} $ 在(完全的简单图,**最大度不超过n-1**
2828

2929
接着,我们每次排序(逆序),首先把最大的度数(设为k)安排出去,看看是否足够多的点(k个)来满足它需要的边(就是从前往后扫,每个度-1)。如果不够,说明只能安排重边,即不能构成简单图。
3030

@@ -53,8 +53,6 @@ def can_be_a_graph(degrees):
5353

5454
紧接着,我们每次排序(逆序),如果能构成简单的图,度数最大的点x(设度数为k)必然可以从其他较大的k个节点中连接一条边,因此如果有k个节点,那么不会有重边出现,这个点可以安排,如果不满足k个节点,显然不能构成简单图。
5555

56-
57-
5856
### 时间复杂度分析
5957

6058
上述的做法,每次进行排序,每次排序复杂度为O(nlogn),一共有n次排序,因此复杂度O(n^2^logn)
@@ -111,7 +109,7 @@ fte_i_k = fte = max(fte,pte+f[k])
111109

112110
由于f[i] > f[k],那么有fte_k\_i > fte_k\_i\_1(因为f[i] > f[k]并且pte变大了)
113111

114-
而 fte_i_k >= fte\_i\_k\_1(pte变大,但是fk] < f[i]),也就是说,交换i和k不会增大fte的值。
112+
而 fte_i_k >= fte\_i\_k\_1(pte变大,但是f[k] < f[i]),也就是说,交换i和k不会增大fte的值。
115113

116114
因此,我们的贪心算法是正确的。
117115

@@ -155,7 +153,7 @@ def min_radar(points, d):
155153
px = points[0].x + sqrt(d * d - points[0].y * points[0].y)
156154
ans = 1
157155
for i in range(1,len(points)):
158-
if (px - points[i].x)**2 + points[i].y * points[i].y <= d*d: continue
156+
if (px - points[i].x)**2 + points[i].y ** 2 <= d*d: continue
159157
cx = points[i].x + sqrt(d * d - points[i].y * points[i].y)
160158
if cx < px:
161159
px = cx

4_LP/readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ $$
163163
\end{array}\nonumber
164164
$$
165165

166-
还没写完
166+
167167

168168

169169

5_Network_flow/Assignment5_NF.pdf

48.2 KB
Binary file not shown.

5_Network_flow/readme.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def test(m, n, row, col):
131131
遍历E中的边,重复下述的过程:
132132

133133
- 对于当前的边e~i~,将其容量+1
134-
- 继续运行最大流算法,得到新的最小割 C~i~其大小为|C~i~|
134+
- 继续运行最大流算法,得到新的最小割 C~i~其大小(即最大流流量)为|C~i~|
135135
-|C~i~| = |C|, 说明|C~i~| 也是最小割,就是说G的最小割不唯一,return False
136136
- 恢复e~i~ 的值
137137

@@ -293,11 +293,13 @@ $$
293293
$$
294294
We add a 'weight' which is called y~e~ for every edge.
295295

296-
The two constraints says every path has a non-negative weight and sum of every path's weight must be at least 1. Actually, given a cut A-B(and $s \in A, t\in B$) , if edge e connect A and B(in other words, $u \in A, v\in B\quad(u,v) $ is two vertices of edge e,and $ (u,v)$ is a cut edge ),we set y~e~ = 1, otherwise, we set y~e~ = 0.
296+
The two constraints says every path has a non-negative weight and sum of every path's weight must be at least 1. Actually, given a cut A-B(and $s \in A, t\in B$) , if edge e connect A and B(in other words, $u \in A, v\in B\quad(u,v) $ is two vertices of edge e,and $ (u,v)$ is a cut edge ),we set y~e~ = 1, otherwise, we set y~e~ = 0.
297297

298298
So, the objective function is just to minimize the sum of capacity multiply its weight. Obviously, it is designed to solve the minimum cut problem.
299299

300+
目标函数中 $y_e$ 表示一条边选或者不选,为1选,为2不选,因此目标函数是求最小割。
300301

302+
第一个约束条件表示从s到t中的路径,至少有一条边在割上。
301303

302304

303305

6_NP/Assignment6_NP.pdf

126 KB
Binary file not shown.

0 commit comments

Comments
 (0)