Skip to content

Commit 6563f03

Browse files
authored
Merge pull request apachecn#57 from apachecn/master
1
2 parents 0e1d445 + 4b963b8 commit 6563f03

13 files changed

+1202
-63
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# 312. Burst Balloons
2+
3+
**<font color=red>难度: Hard</font>**
4+
5+
## 刷题内容
6+
7+
> 原题连接
8+
9+
* https://leetcode.com/problems/burst-balloons/
10+
11+
> 内容描述
12+
13+
```
14+
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins. Here left and right are adjacent indices of i. After the burst, the left and right then becomes adjacent.
15+
16+
Find the maximum coins you can collect by bursting the balloons wisely.
17+
18+
Note:
19+
20+
You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.
21+
0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100
22+
Example:
23+
24+
Input: [3,1,5,8]
25+
Output: 167
26+
Explanation: nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
27+
coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
28+
```
29+
30+
## 解题方案
31+
32+
> 思路 1
33+
******- 时间复杂度: O(N^3)******- 空间复杂度: O(N^2)******
34+
35+
典型dp, dp[left][right]代表爆掉left到right中间(not inclusive)所有的balloons, 所能得到的最大coins
36+
37+
状态方程为:
38+
```dp[left][right] = max[(nums[i-1] * nums[i] * nums[i+1] + dp[left][i] + dp[i][right]) for i in range(left+1, right)]```
39+
其中i为最后一个被爆掉的气球
40+
41+
这里的思考为:如果我们从第一个被爆掉的气球开始考虑,后面的情况我们不知道当前被爆掉的气球左右两边都是谁,也就写不出状态方程了
42+
43+
但是如果从最后一个被爆掉的气球开始考虑的话,那它的左右两边肯定都是1,即nums[-1]和nums[n]
44+
并且根据它分成的左右两边d[left][i]和dp[i][right]也可以通过同样的方法一步步算到最后
45+
46+
47+
这里还有一个trick,就是对于nums[i] = 0的气球最开始就可以直接删掉了,因为对于我们的最终结果没有任何影响
48+
49+
beats 59.76%
50+
51+
```python
52+
class Solution(object):
53+
def maxCoins(self, nums):
54+
"""
55+
:type nums: List[int]
56+
:rtype: int
57+
"""
58+
nums = [1] + [i for i in nums if i > 0] + [1]
59+
dp = [[0] * len(nums) for _ in range(len(nums))]
60+
61+
for gap in range(2, len(nums)):
62+
for left in range(len(nums) - gap):
63+
right = left + gap
64+
for i in range(left + 1, right):
65+
dp[left][right] = max(dp[left][right],
66+
nums[left] * nums[i] * nums[right] + dp[left][i] + dp[i][right]) # i为最后一个被爆掉的气球
67+
return dp[0][-1]
68+
```
69+
70+
71+
另外看到一个很有意思的[post](https://leetcode.com/problems/burst-balloons/discuss/76241/Another-way-to-think-of-this-problem-(Matrix-chain-multiplication))
72+
73+
```
74+
If you think of bursting a balloon as multiplying two adjacent matrices, then this problem is exactly the classical DP problem
75+
Matrix-chain multiplication found in section 15.2 in the book Introduction to Algorithms (2nd edition).
76+
77+
For example, given [3,5,8] and bursting 5, the number of coins you get is the number of scalar multiplications you need to do
78+
to multiply two matrices A[3*5] and B[5*8]. So in this example, the original problem is actually the same as given a matrix
79+
chain A[1*3]*B[3*5]*C[5*8]*D[8*1], fully parenthesize it so that the total number of scalar multiplications is maximized,
80+
although the orignal matrix-chain multiplication problem in the book asks to minimize it. Then you can see it clearly as a
81+
classical DP problem.
82+
```
83+
84+
85+
86+
87+
88+
89+
90+
91+
92+
93+
94+
95+
96+
97+
98+
99+
100+
101+
102+
103+
104+
105+
106+
107+
108+
109+
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# 395. Longest Substring with At Least K Repeating Characters
2+
3+
**<font color=red>难度: Medium</font>**
4+
5+
## 刷题内容
6+
7+
> 原题连接
8+
9+
* https://leetcode.com/problems/longest-substring-with-at-least-k-repeating-characters/
10+
11+
> 内容描述
12+
13+
```
14+
Find the length of the longest substring T of a given string (consists of lowercase letters only) such that every character in T appears no less than k times.
15+
16+
Example 1:
17+
18+
Input:
19+
s = "aaabb", k = 3
20+
21+
Output:
22+
3
23+
24+
The longest substring is "aaa", as 'a' is repeated 3 times.
25+
Example 2:
26+
27+
Input:
28+
s = "ababbc", k = 2
29+
30+
Output:
31+
5
32+
33+
The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
34+
```
35+
36+
## 解题方案
37+
38+
> 思路 1
39+
******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
40+
41+
42+
因为一共就只有26种不同的英文字母字符,所以我们只要做26次遍历即可。
43+
- 第1次找到一个最长的substring,它里面只有1种不同的字符,并且这1种字符出现至少k次
44+
- 第2次找到一个最长的substring,它里面只有2种不同的字符,并且这2种字符都出现至少k次
45+
- 第3次找到一个最长的substring,它里面只有2种不同的字符,并且这2种字符都出现至少k次
46+
- 第4次找到一个最长的substring,它里面只有2种不同的字符,并且这2种字符都出现至少k次
47+
- .........................................................................
48+
- .........................................................................
49+
- .........................................................................
50+
- 第26次找到一个最长的substring,它里面只有26种不同的字符,并且这26种字符都出现至少k次
51+
52+
然后我们最终取最长的那个长度就可以了,大体就是slide window的思想,beats 15.57%
53+
54+
```python
55+
class Solution(object):
56+
def longestSubstring(self, s, k):
57+
"""
58+
:type s: str
59+
:type k: int
60+
:rtype: int
61+
"""
62+
if k == 0 or len(s) == 0:
63+
return len(s)
64+
res = 0
65+
for ucc in range(1, 27):
66+
res = max(res, self.longestSubstringWithUcc(s, k, ucc))
67+
return res
68+
69+
def longestSubstringWithUcc(self, s, k, ucc): # ucc: unique_chr_cnt
70+
count = collections.defaultdict(int)
71+
unique, no_less_than_k, start, res = 0, 0, 0, 0
72+
for i, c in enumerate(s):
73+
count[c] += 1
74+
if count[c] == 1:
75+
unique += 1
76+
if count[c] == k:
77+
no_less_than_k += 1
78+
while start <= i and unique > ucc:
79+
if count[s[start]] == 1:
80+
unique -= 1
81+
if count[s[start]] == k:
82+
no_less_than_k -= 1
83+
count[s[start]] -= 1
84+
start += 1
85+
if unique == ucc and no_less_than_k == ucc:
86+
res = max(res, i - start + 1)
87+
return res
88+
```
89+
90+
91+
92+
93+
> 思路 2
94+
******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
95+
96+
还有一个更好的方法,就是我们可以先计算出s中每种字符的个数,然后如果有一个字符的出现次数少于k次,那么说明任何包含这个字符的substring都不满足要求
97+
98+
因此我们可以用这个字符来split整个字符串s,然后对split出来的各个substring继续递归调用longestSubstring函数即可,返回其中的最大值。
99+
100+
如果所有的字符出现次数都不小于k次,那么说明整个字符串s都满足,我们直接返回len(s)
101+
102+
beats 32.51%
103+
104+
```python
105+
class Solution(object):
106+
def longestSubstring(self, s, k):
107+
"""
108+
:type s: str
109+
:type k: int
110+
:rtype: int
111+
"""
112+
lookup = collections.Counter(s)
113+
for c in lookup:
114+
if lookup[c] < k:
115+
return max(self.longestSubstring(t, k) for t in s.split(c))
116+
return len(s)
117+
```
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+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# 482. License Key Formatting
2+
3+
**<font color=red>难度: Easy</font>**
4+
5+
## 刷题内容
6+
7+
> 原题连接
8+
9+
* https://leetcode.com/problems/license-key-formatting/
10+
11+
> 内容描述
12+
13+
```
14+
You are given a license key represented as a string S which consists only alphanumeric character and dashes. The string is separated into N+1 groups by N dashes.
15+
16+
Given a number K, we would want to reformat the strings such that each group contains exactly K characters, except for the first group which could be shorter than K, but still must contain at least one character. Furthermore, there must be a dash inserted between two groups and all lowercase letters should be converted to uppercase.
17+
18+
Given a non-empty string S and a number K, format the string according to the rules described above.
19+
20+
Example 1:
21+
Input: S = "5F3Z-2e-9-w", K = 4
22+
23+
Output: "5F3Z-2E9W"
24+
25+
Explanation: The string S has been split into two parts, each part has 4 characters.
26+
Note that the two extra dashes are not needed and can be removed.
27+
Example 2:
28+
Input: S = "2-5g-3-J", K = 2
29+
30+
Output: "2-5G-3J"
31+
32+
Explanation: The string S has been split into three parts, each part has 2 characters except the first part as it could be shorter as mentioned above.
33+
Note:
34+
The length of string S will not exceed 12,000, and K is a positive integer.
35+
String S consists only of alphanumerical characters (a-z and/or A-Z and/or 0-9) and dashes(-).
36+
String S is non-empty.
37+
```
38+
39+
## 解题方案
40+
41+
> 思路 1
42+
******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
43+
44+
sb题没什么好说的
45+
46+
beats 79.41%
47+
48+
```python
49+
class Solution(object):
50+
def licenseKeyFormatting(self, S, K):
51+
"""
52+
:type S: str
53+
:type K: int
54+
:rtype: str
55+
"""
56+
S = S.replace('-', '').upper()[::-1]
57+
return '-'.join(S[i:i+K] for i in range(0, len(S), K))[::-1]
58+
```

0 commit comments

Comments
 (0)