Skip to content

Commit 1eb6d91

Browse files
authored
Merge pull request apachecn#15 from apachecn/master
1
2 parents dee05ce + fff858d commit 1eb6d91

File tree

7 files changed

+760
-25
lines changed

7 files changed

+760
-25
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# 376. Wiggle Subsequence
2+
3+
**<font color=red>难度: Medium</font>**
4+
5+
## 刷题内容
6+
7+
> 原题连接
8+
9+
* https://leetcode.com/problems/wiggle-subsequence/description/
10+
11+
> 内容描述
12+
13+
```
14+
A sequence of numbers is called a wiggle sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a wiggle sequence.
15+
16+
For example, [1,7,4,9,2,5] is a wiggle sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, [1,4,7,2,5] and [1,7,4,5,5] are not wiggle sequences, the first because its first two differences are positive and the second because its last difference is zero.
17+
18+
Given a sequence of integers, return the length of the longest subsequence that is a wiggle sequence. A subsequence is obtained by deleting some number of elements (eventually, also zero) from the original sequence, leaving the remaining elements in their original order.
19+
20+
Example 1:
21+
22+
Input: [1,7,4,9,2,5]
23+
Output: 6
24+
Explanation: The entire sequence is a wiggle sequence.
25+
Example 2:
26+
27+
Input: [1,17,5,10,13,15,10,5,16,8]
28+
Output: 7
29+
Explanation: There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8].
30+
Example 3:
31+
32+
Input: [1,2,3,4,5,6,7,8,9]
33+
Output: 2
34+
Follow up:
35+
Can you do it in O(n) time?
36+
```
37+
38+
## 解题方案
39+
40+
> 思路 1
41+
******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
42+
43+
44+
45+
很简单的思想,从index为1的num开始看
46+
- 如果比之前一个数字大的话,那么此时就可以看作之前最后一下是negative的序列的后续num
47+
- 如果比之前一个数字小的话,那么此时就可以看作之前最后一下是positive的序列的后续num
48+
- 如果与之前一个数字相等的话,那么当前这个数字可以直接删除不要
49+
50+
51+
```python
52+
class Solution(object):
53+
def wiggleMaxLength(self, nums):
54+
"""
55+
:type nums: List[int]
56+
:rtype: int
57+
"""
58+
if not nums or len(nums) == 0:
59+
return 0
60+
positive, negative = 1, 1
61+
for i in range(1, len(nums)):
62+
if nums[i] > nums[i-1]:
63+
positive = negative + 1
64+
elif nums[i] < nums[i-1]:
65+
negative = positive + 1
66+
return max(positive, negative)
67+
```

docs/Leetcode_Solutions/Python/924._Minimize_Malware_Spread.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ graph[i][i] = 1
4949
## 解题方案
5050

5151
> 思路 1
52-
******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
52+
******- 时间复杂度: O(len(graph)^2)******- 空间复杂度: O(len(graph))******
5353

5454

5555

@@ -59,11 +59,11 @@ graph[i][i] = 1
5959

6060
思路就是看看initial里面哪个index最小的点所在的联通分量size最大
6161

62-
其中要注意每个initial中元素ini所在的联通分量我们还要去除它里面含有的本身就在initial中的其他元素,因为对于这些元素,事实上即使我们删除了ini,也minimize不了它们。所以要算一下每个initial里面的元素所在的联通分量里面包含的其他的initial元素的个数,代码中带dup表示
62+
其中要注意每个initial中元素ini所在的联通分量我们还要去除它里面含有的本身就在initial中的其他元素,因为对于这些元素,事实上即使我们删除了ini,也minimize不了它们。所以要算一下每个initial里面的元素所在的联通分量里面包含的其他的initial元素的个数,代码中用dup表示
6363

6464
graph长度为N,
6565

66-
find()时间复杂度为O(N), union为O(1),所以最终时间复杂度为O(N^2)
66+
find()时间复杂度为O(N), union为O(1),所以最终时间复杂度为O(len(graph)^2)
6767

6868
空间为O(N)
6969

@@ -88,9 +88,10 @@ class Solution(object):
8888

8989
uf = [i for i in range(len(graph))]
9090
for i in range(len(graph)):
91-
for j in range(len(graph[0])):
91+
for j in range(i+1, len(graph)):
9292
if graph[i][j]:
9393
union(i, j)
94+
9495
lookup, dup = {}, {}
9596
for i in range(len(graph)):
9697
root = find(i)
@@ -102,10 +103,10 @@ class Solution(object):
102103
max_component_size = max(component_sizes_of_initial)
103104

104105
res = []
105-
for i in range(len(component_sizes_of_initial)):
106+
for i in range(len(initial)):
106107
if component_sizes_of_initial[i] == max_component_size:
107108
res.append(initial[i])
108-
return min(res)
109+
return min(res)
109110
```
110111

111112

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# 925. Long Pressed Name
2+
3+
**<font color=red>难度: Easy</font>**
4+
5+
## 刷题内容
6+
7+
> 原题连接
8+
9+
* https://leetcode.com/problems/long-pressed-name/description/
10+
11+
> 内容描述
12+
13+
```
14+
Your friend is typing his name into a keyboard. Sometimes, when typing a character c, the key might get long pressed, and the character will be typed 1 or more times.
15+
16+
You examine the typed characters of the keyboard. Return True if it is possible that it was your friends name, with some characters (possibly none) being long pressed.
17+
18+
19+
20+
Example 1:
21+
22+
Input: name = "alex", typed = "aaleex"
23+
Output: true
24+
Explanation: 'a' and 'e' in 'alex' were long pressed.
25+
Example 2:
26+
27+
Input: name = "saeed", typed = "ssaaedd"
28+
Output: false
29+
Explanation: 'e' must have been pressed twice, but it wasn't in the typed output.
30+
Example 3:
31+
32+
Input: name = "leelee", typed = "lleeelee"
33+
Output: true
34+
Example 4:
35+
36+
Input: name = "laiden", typed = "laiden"
37+
Output: true
38+
Explanation: It's not necessary to long press any character.
39+
40+
41+
Note:
42+
43+
name.length <= 1000
44+
typed.length <= 1000
45+
The characters of name and typed are lowercase letters.
46+
```
47+
48+
## 解题方案
49+
50+
> 思路 1
51+
******- 时间复杂度: O(max(len(name),len(typed)))******- 空间复杂度: O(1)******
52+
53+
54+
两个字符串从index为0开始比较
55+
56+
- 如果该字符相同就同时往后挪, i += 1, j += 1
57+
- 如果该字符不相同,那么
58+
- 如果typed的字符和name的前一个字符相等,那么j += 1
59+
- 如果typed的字符和name的前一个字符不相等,肯定不行,直接返回False
60+
- while循环完了,如果 i < len(name),那么说明name没有被比较晚,肯定不行,直接返回False
61+
- 如果typed还没有完,即j < len(typed),那么如果typed剩下的所有字符不是都与name的最后一个字符相等的话,就说明不行,直接返回False,否则返回True
62+
63+
64+
```python
65+
class Solution(object):
66+
def isLongPressedName(self, name, typed):
67+
"""
68+
:type name: str
69+
:type typed: str
70+
:rtype: bool
71+
"""
72+
i, j = 0, 0
73+
prev = None
74+
75+
while i < len(name) and j < len(typed):
76+
if name[i] == typed[j]:
77+
prev = name[i]
78+
i += 1
79+
j += 1
80+
else:
81+
if typed[j] == prev:
82+
j += 1
83+
else:
84+
return False
85+
if i < len(name):
86+
return False
87+
88+
while j < len(typed):
89+
if typed[j] != prev:
90+
return False
91+
else:
92+
j += 1
93+
94+
return True
95+
```
96+
97+
98+
99+
100+
101+
102+
103+
104+
105+
106+
107+
108+
109+
110+
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# 926. Flip String to Monotone Increasing
2+
3+
**<font color=red>难度: Medium</font>**
4+
5+
## 刷题内容
6+
7+
> 原题连接
8+
9+
* https://leetcode.com/problems/flip-string-to-monotone-increasing/description/
10+
11+
> 内容描述
12+
13+
```
14+
A string of '0's and '1's is monotone increasing if it consists of some number of '0's (possibly 0), followed by some number of '1's (also possibly 0.)
15+
16+
We are given a string S of '0's and '1's, and we may flip any '0' to a '1' or a '1' to a '0'.
17+
18+
Return the minimum number of flips to make S monotone increasing.
19+
20+
21+
22+
Example 1:
23+
24+
Input: "00110"
25+
Output: 1
26+
Explanation: We flip the last digit to get 00111.
27+
Example 2:
28+
29+
Input: "010110"
30+
Output: 2
31+
Explanation: We flip to get 011111, or alternatively 000111.
32+
Example 3:
33+
34+
Input: "00011000"
35+
Output: 2
36+
Explanation: We flip to get 00000000.
37+
38+
39+
Note:
40+
41+
1 <= S.length <= 20000
42+
S only consists of '0' and '1' characters.
43+
```
44+
45+
## 解题方案
46+
47+
> 思路 1
48+
******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
49+
50+
51+
52+
53+
54+
55+
56+
我们就这样想吧,要想最后满足要求,我们的字符串S肯定是'000000001111111'的形式,可以全为0还可以全为1
57+
58+
因此我们每种情况都考虑一下,取其中改变次数最小的那个次数,
59+
60+
即让前i个字符都变成0,后面len(S)-i个字符都变成1所需要的次数
61+
62+
63+
64+
```python
65+
class Solution(object):
66+
def minFlipsMonoIncr(self, S):
67+
"""
68+
:type S: str
69+
:rtype: int
70+
"""
71+
if not S or len(S) <= 1:
72+
return 0
73+
count_0, count_1 = [0] * (len(S)+1), [0] * (len(S)+1)
74+
for i, v in enumerate(S):
75+
if v == '0':
76+
count_0[i+1] = count_0[i] + 1
77+
count_1[i+1] = count_1[i]
78+
else:
79+
count_0[i+1] = count_0[i]
80+
count_1[i+1] = count_1[i] + 1
81+
res = sys.maxsize
82+
for i in range(len(S)+1): # 代表S前面i个字符全都是'0'
83+
res = min(res, count_1[i] + count_0[-1] - count_0[i])
84+
return res
85+
```
86+
87+
88+
89+
> 思路 2
90+
******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
91+
92+
跟刚才的思想一样,我们只要把左边的1全部变成0, 右边的0全部变成1,然后取最小的那次就行了
93+
94+
95+
```python
96+
class Solution(object):
97+
def minFlipsMonoIncr(self, S):
98+
"""
99+
:type S: str
100+
:rtype: int
101+
"""
102+
r0, r1, l0, l1 = 0, 0, 0, 0
103+
for i, c in enumerate(S):
104+
if c == '0':
105+
r0 += 1 # 从idx为0开始,右边有多少个0
106+
else:
107+
r1 += 1 # 从idx为0开始,右边有多少个1
108+
res = r0
109+
for i, c in enumerate(S):
110+
if c == '0':
111+
r0 -= 1
112+
l0 += 1
113+
else:
114+
r1 -= 1
115+
l1 += 1
116+
res = min(l1 + r0, res) # 此时我们要将左边的1全部变成0,右边的0全部变成1
117+
return res
118+
```
119+
120+
121+
122+
123+
124+
125+
126+
127+
128+
129+
130+
131+
132+
133+
134+
135+
136+
137+
138+
139+
140+
141+
142+
143+
144+
145+
146+
147+
148+
149+
150+
151+

0 commit comments

Comments
 (0)