Skip to content

Commit ce3495d

Browse files
authored
Merge pull request #519 from garrettmac/english-thinking-translation
English thinking translation
2 parents d46a3a5 + 1c5b59b commit ce3495d

39 files changed

+8939
-129
lines changed

Diff for: thinkings/DFS.en.md

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Depth first traversal
2+
3+
## Introduction
4+
5+
Depth-First-Search (DFS) is an algorithm used to traverse or search a tree or graph. Traverse the nodes of the tree along the depth of the tree, and search for the branches of the tree as deep as possible. When the edge of node v has been explored, the search will go back to the starting node of the edge where Node V was found. This process continues until all nodes reachable from the source node have been found. If there are still undiscovered nodes, select one of them as the source node and repeat the above process. The entire process is repeated until all nodes are accessed. It is a blind search.
6+
7+
Depth-first search is a classic algorithm in graph theory. The depth-first search algorithm can be used to generate a corresponding topological sorting table for the target graph. The topological sorting table can be used to easily solve many related graph theory problems, such as the maximum path problem and so on.
8+
9+
For inventing the "depth-first search algorithm", John Hopcroft and Robert Tayan jointly won the highest award in the field of computers: the Turing Award in 1986.
10+
11+
As of now (2020-02-21), there are 129 questions in the LeetCode for depth-first traversal. The question type in LeetCode is definitely a super big one. For tree problems, we can basically use DFS to solve them, and even we can do breadth-first traversal based on DFS. It does not necessarily mean that DFS cannot do BFS (breadth-first traversal). And since we can usually do DFS based on recursion, the algorithm will be more concise. In situations where performance is very important, I suggest you use iteration, otherwise try to use recursion, which is not only simple and fast to write, but also not error-prone.
12+
13+
In addition, in-depth priority traversal can be linked by combining backtracking topics. It is recommended to put these two topics together to learn.
14+
15+
The concept of DFS comes from graph theory, but there are still some differences between DFS in search and DFS in graph theory. DFS in search generally refers to violent enumeration through recursive functions.
16+
17+
## Algorithm flow
18+
19+
1. First put the root node in the **stack**.
20+
2. Take the first node from _stack_ and verify whether it is the target. If the target is found, the search ends and the result is returned. Otherwise, add one of its direct child nodes that have not been tested to the stack.
21+
3. Repeat Step 2.
22+
4. If there is no direct child node that has not been detected. Add the previous node to the **stack**.
23+
Repeat Step 2.
24+
5. Repeat step 4.
25+
6. If **stack** is empty, it means that the entire picture has been checked-that is, there are no targets to search for in the picture. End the search and return “Target not found".
26+
27+
> The stack here can be understood as a self-implemented stack, or as a call stack
28+
29+
## Algorithm Template
30+
31+
```js
32+
const visited = {}
33+
function dfs(i) {
34+
if (meet specific conditions) {
35+
// Return result or exit search space
36+
}
37+
38+
Visited[i] = true// Mark the current status as searched
39+
for (according to the next state j that i can reach) {
40+
if (! Visited[j]) { / / If status j has not been searched
41+
dfs(j)
42+
}
43+
}
44+
}
45+
```
46+
47+
## Topic recommendation
48+
49+
These are a few DFS topics that I recently summarized, and will continue to be updated in the future~
50+
51+
- [200. Number of islands] (https://leetcode-cn.com/problems/number-of-islands/solution/mo-ban-ti-dao-yu-dfspython3-by-fe-lucifer-2 /) Medium
52+
53+
- [695. The largest area of the island] (https://leetcode-cn.com/problems/max-area-of-island/solution/mo-ban-ti-dao-yu-dfspython3-by-fe-lucifer /) Medium
54+
- [979. Allocate coins in a binary tree] (https://leetcode-cn.com/problems/distribute-coins-in-binary-tree/solution/tu-jie-dfspython3-by-fe-lucifer /) Medium

Diff for: thinkings/GCD.en.md

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# How do I use the ** Greatest common divisor** spike algorithm problem
2+
3+
There is a special study on the greatest common divisor. Although in LeetCode, there is no problem that directly allows you to solve the greatest common divisor. But there are some problems that indirectly require you to solve the greatest common divisor.
4+
5+
For example:
6+
7+
- [914. Card grouping] (https://leetcode-cn.com/problems/x-of-a-kind-in-a-deck-of-cards/solution/python3-zui-da-gong-yue-shu-914-qia-pai-fen-zu-by -/ "914. Card grouping")
8+
- [365. Kettle problem) (https://leetcode-cn.com/problems/water-and-jug-problem/solution/bfszui-da-gong-yue-shu-by-fe-lucifer /"365. Kettle problem")
9+
- [1071. The greatest common factor of a string] (https://leetcode-cn.com/problems/greatest-common-divisor-of-strings/solution/1071-zi-fu-chuan-de-zui-da-gong-yin-zi-zui-da-gong / "1071. The greatest common factor of the string")
10+
11+
Therefore, how to solve the greatest common divisor is important.
12+
13+
## How to find the greatest common divisor?
14+
15+
### Definition method
16+
17+
```python
18+
def GCD(a: int, b: int) -> int:
19+
smaller = min(a, b)
20+
while smaller:
21+
if a % smaller == 0 and b % smaller == 0:
22+
return smaller
23+
smaller -= 1
24+
```
25+
26+
**Complexity analysis**
27+
28+
-Time complexity: The best case scenario is to execute a loop body, and the worst case scenario is to loop to a smaller of 1, so the total time complexity is $O(N)$, where N is the smaller number in a and B.
29+
-Spatial complexity:$O(1)$.
30+
31+
### Tossing and dividing
32+
33+
If we need to calculate the greatest common divisor of a and b, use the tossing and turning division method. First, we first calculate the remainder c of a divided by b, and transform the problem into the greatest common divisor of b and c; then calculate the remainder d of b divided by c, and transform the problem into the greatest common divisor of c and d; then calculate the remainder e of c divided by d, and transform the problem into the greatest common divisor of d and E. . . . . . And so on, gradually convert the operation between the two larger integers into the operation between the two smaller integers until the two numbers are divisible by.
34+
35+
```python
36+
def GCD(a: int, b: int) -> int:
37+
return a if b == 0 else GCD(b, a % b)
38+
```
39+
40+
**Complexity analysis**
41+
42+
-Time complexity:$O(log(max(a,b)))$
43+
-Spatial complexity: Spatial complexity depends on the depth of recursion, so the spatial complexity is $O(log(max(a, b)))$
44+
45+
### More phase derogation technique
46+
47+
If the tossing and turning division method is large when a and b are both large, the performance of a % b will be lower. In China, the "Nine Chapters of Arithmetic" mentions a kind of [more subtraction technique] similar to tossing and Turning Subtraction method (https://zh.wikisource.org/wiki/%E4%B9%9D%E7%AB%A0%E7%AE%97%E8%A1%93#-.7BA.7Czh-hans:.E5.8D.B7.3Bzh-hant:.E5.8D.B7.7D-.E7.AC.AC.E4.B8.80.E3.80.80.E6.96.B9.E7.94.B0.E4.BB.A5.E5.BE.A1.E7.94.B0.E7.96.87.E7.95.8C.E5.9F.9F "More derogatory technique"). Its principle is: `For two positive integers a and b (a>b), their greatest common divisor is equal to the difference c of a-b and the greatest common divisor of the smaller number B. `.
48+
49+
```python
50+
def GCD(a: int, b: int) -> int:
51+
if a == b:
52+
return a
53+
if a < b:
54+
return GCD(b - a, a)
55+
return GCD(a - b, b)
56+
```
57+
58+
The above code will report a stack overflow. The reason is that if the difference between a and b is relatively large, the number of recursions will increase significantly, which is much greater than the recursion depth of tossing and dividing, and the worst time complexity is O(max(a, b))). At this time, we can combine the "tossing and turning division method" and the "more phase derogation technique", so that we can obtain better performance in various situations.
59+
60+
## Visualize and explain
61+
62+
Below we will give a graphic explanation of the above process. In fact, this is also the explanation method in the textbook. I just copied it and added my own understanding. Let's use an example to explain:
63+
64+
If we have a piece of land of 1680 meters \*640 meters, we want to talk about land divided into squares, and we want to make the side length of the square land as large as possible. How should we design the algorithm?
65+
66+
In fact, this is an application scenario for the greatest common divisor. Our goal is to solve the greatest common divisor of 1680 and 640.
67+
68+
![](https://tva1.sinaimg.cn/large/007S8ZIlly1ghluj0ysrjj30f104zmxs.jpg)
69+
70+
Dividing 1680 meters\*640 meters of land is equivalent to dividing 400 meters\*640 meters of land. Why? If the side length of a square divided by 400 meters\*640 meters is x, then there is 640% x==0, then it will definitely satisfy the remaining two pieces of 640 meters\*640 meters.
71+
72+
![](https://tva1.sinaimg.cn/large/007S8ZIlly1ghluj6lpjej30g805aaap.jpg)
73+
74+
We continue to divide the above:
75+
76+
![](https://tva1.sinaimg.cn/large/007S8ZIlly1ghlujd4rhbj307x08v74i.jpg)
77+
78+
Until the side length is 80, there is no need to proceed.
79+
80+
![](https://tva1.sinaimg.cn/large/007S8ZIlly1ghlujgvkvbj30aa04umx2.jpg)
81+
82+
## Instance analysis
83+
84+
### Title description
85+
86+
```
87+
To give you three numbers a, b, and c, you need to find the value of the nth ordered sequence (n starts from 0). This ordered sequence is composed of integer multiples of a, b, and C.
88+
89+
For example:
90+
n = 8
91+
a = 2
92+
b = 5
93+
c = 7
94+
95+
Since the ordered sequence composed of integer multiples of 2, 5, and 7 is [1, 2, 4, 5, 6, 7, 8, 10, 12, . . . ], so we need to return 12.
96+
97+
Note: We agree that the first of the ordered sequence will always be 1.
98+
```
99+
100+
### Idea
101+
102+
You can go through [this website] (https://binarysearch.com/problems/Divisible-Numbers "binary search") Online verification.
103+
104+
A simple idea is to use a heap to do it. The only thing to pay attention to is the deletions. We can use a hash table to record the numbers that have appeared in order to achieve the purpose of deletions.
105+
106+
code:
107+
108+
```py
109+
ss Solution:
110+
def solve(self, n, a, b, c):
111+
seen = set()
112+
h = [(a, a, 1), (b, b, 1), (c, c, 1)]
113+
heapq. heapify(h)
114+
115+
while True:
116+
cur, base, times = heapq. heappop(h)
117+
if cur not in seen:
118+
n -= 1
119+
seen. add(cur)
120+
if n == 0:
121+
return cur
122+
heapq. heappush(h, (base * (times + 1), base, times + 1))
123+
```
124+
125+
If you don't understand this solution, you can first take a look at what I wrote before [After almost brushing all the piles of questions, I found these things. 。 。 (Second bullet)](https://lucifer . ren/blog/2021/01/19/ heap-2/ "I have almost finished brushing all the piles of questions, and I found these things. 。 。 (Second bullet)")
126+
127+
However, the time complexity of this approach is too high. Is there a better approach?
128+
129+
In fact, we can divide the search space. First think about a problem. If a number x is given, there are several values less than or equal to x in an ordered sequence.
130+
131+
Is the answer x// a + x// b + x// c?
132+
133+
> / / Is the floor except
134+
135+
Unfortunately, it is not. For example, a= 2, b= 4, n= 4, the answer is obviously not 4 // 2 + 4 // 4 = 3, But 2. The reason for the error here is that 4 is calculated twice, one time it is $2 * 2 = 4$, and the other time it is $4 * 1 = 4$.
136+
137+
In order to solve this problem, we can use the knowledge of set theory.
138+
139+
Gather a little bit of knowledge:
140+
141+
-If the set of values in the ordered sequence that are less than or equal to x can be divisible by x and are multiples of A is SA, the size of the set is A
142+
-If the set of values in the ordered sequence that are less than or equal to x can be divisible by x and are multiples of B is SB, the size of the set is B
143+
-If the set of values in an ordered sequence that are less than or equal to x that can be divisible by x and are multiples of C is SC, the size of the set is C
144+
145+
Then the final answer is the number of numbers in the large set (which needs to be duplicated) composed of SA, SB, and SC, that is,:
146+
147+
$$
148+
A + B + C - sizeof(SA \cap SB) - sizeof(SB \cap SC) - sizeof(SA \cap SC) + sizeof(SA \cap SB \cap SC)
149+
$$
150+
151+
The question is transformed into how to find the number of intersections of sets A and B?
152+
153+
> The method of finding the intersection of A and B, B and C, A and C, and even A, B, and C is the same.
154+
155+
In fact, the number of intersections of SA and SB is x//lcm(A, B), where lcm is the least common multiple of A and B. The least common multiple can be calculated by the greatest common divisor:
156+
157+
```py
158+
def lcm(x, y):
159+
return x * y // gcd(x, y)
160+
161+
```
162+
163+
The next step is the two-part routine. If you can't understand the two-part part, please take a look at my [two-part topic] (https://github.com/azl397985856/leetcode/blob/master/91/binary-search.md "Two-part special").
164+
165+
### Code (Python3)
166+
167+
```py
168+
class Solution:
169+
def solve(self, n, a, b, c):
170+
def gcd(x, y):
171+
if y == 0:
172+
return x
173+
return gcd(y, x % y)
174+
175+
def lcm(x, y):
176+
return x * y // gcd(x, y)
177+
178+
def possible(mid):
179+
return (mid // a + mid // b + mid // c - mid // lcm(a, b) - mid // lcm(b, c) - mid // lcm(a, c) + mid // lcm(a, lcm(b, c))) >= n
180+
181+
l, r = 1, n * max(a, b, c)
182+
while l <= r:
183+
mid = (l + r) // 2
184+
if possible(mid):
185+
r = mid - 1
186+
else:
187+
l = mid + 1
188+
return l
189+
190+
```
191+
192+
**Complexity analysis**
193+
194+
-Time complexity:$logn$.
195+
-Spatial complexity: The depth of the recursive tree of gcd and lcm is basically negligible.
196+
197+
## Summary
198+
199+
Through this article, we not only understand the concept of the greatest common divisor and the method of finding it. It also visually perceives the **principle** of the calculation of the greatest common divisor. The greatest common divisor and the least common multiple are two similar concepts. There are not many questions about the greatest common divisor and the least common multiple in Li Buckle. You can find these questions through the Mathematics tab. For more information about mathematics knowledge in algorithms, you can refer to this article [Summary of mathematics test points necessary for brushing algorithm questions] (https://mp.weixin.qq.com/s?__biz=MzI4MzUxNjI3OA==&mid=2247485590&idx=1&sn=e3f13aa02fed4d4132146e193eb17cdb&chksm=eb88c48fdcff4d99b44d537459396589b8987f89a8c21085a945ca8d5e2b0b140c13aef81d91&token=1223087516&lang=zh_CN#rd "Summary of math test points necessary for brushing algorithm questions")
200+
201+
> The second part of this article will also be released soon.

Diff for: thinkings/README.en.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Algorithm Topic
2+
3+
The following are some types of questions that I have summarized. Understanding these things in advance is very helpful for future questions. It is strongly recommended to master them first. In addition, my 91-day learning algorithm has also organized the topic at a more granular level. For example, [91-day Learning Algorithm] (. . /91/Readme. md)
4+
5+
First of all, everyone must master the basic data structure, and secondly, the violent method. Brute force is also an algorithm, but what we are pursuing is definitely an algorithm with better performance. Therefore, it is important to understand the algorithm bottleneck of brute force and the characteristics of various data structures, so that you can use this knowledge to approach the optimal solution step by step.
6+
7+
Then there are the algorithms that must be mastered. For example, the search algorithm must be mastered. The scope of the search algorithm is very wide, but the core is search. The different algorithms are different in the way of search. The typical one is BFS and DFS. Of course, the binary method is essentially a search algorithm.
8+
9+
There is also the violent optimization method that must be mastered. Like search, it has a wide range. There are pruning, space for time, etc. Among them, there are many space-for-time changes, such as hash tables, prefix trees, and so on.
10+
11+
If you study around this idea, it won't be too bad. I won't say much about the others. Everyone will slowly appreciate it.
12+
13+
-[Data cable](basic-data-structure.en.md)
14+
-[acyl](linked-list.en.md)
15+
-[Tree topic](tree.en.md)
16+
-[Top(top)](heap.en.md)
17+
-[Next)](heap-2.en.md)
18+
-[Abne four points (wish)](binary-search-1.en.md)
19+
-[Twenty-four points (Part 2)](binary-search-2.en.md)
20+
-[Supernova](binary-tree-traversal.en.md)
21+
-[Dynamic](dynamic-programming.en.md)
22+
-[backtracking](backtrack.en.md)
23+
(Occupation)run-length-encode-and-huffman-encode.en.md)
24+
-[bloom filter](bloom filter. md)
25+
-[Prefix tree(trie. md)
26+
-[My vocational class](https://lucifer.ren/blog/2020/02/03/leetcode-%E6%88%91%E7%9A%84%E6%97%A5%E7%A8%8B%E5%AE%89%E6%8E%92%E8%A1%A8%E7%B3%BB%E5%88%97/)
27+
-[Structure 2]([https://lucifer . . . Ren/Blog/2020/02/08/ %E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%93%E9%A2%98/](https://lucifer.ren/blog/2020/02/08/%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%93%E9%A2%98/))
28+
-[Stressful pressure (pressure + pressure)](slide-window.en.md)
29+
-[Recruitment position](bit.en.md)
30+
-[Island problem] (island. md)
31+
-[Journey of Wisdom](GCD.en.md)
32+
-[Union](union-find.en.md)
33+
-[Second](balanced-tree.en.md)
34+
-[One pumping](reservoid-sampling.en.md)
35+
-[single](monotone-stack.en.md)

0 commit comments

Comments
 (0)