Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 77db8fa

Browse files
author
lucifer
committed
feat: #1297
1 parent 50ad46b commit 77db8fa

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
231231
- [1131.maximum-of-absolute-value-expression](./problems/1131.maximum-of-absolute-value-expression.md) 🆕
232232
- [1186.maximum-subarray-sum-with-one-deletion](./problems/1186.maximum-subarray-sum-with-one-deletion.md) 🆕
233233
- [1218.longest-arithmetic-subsequence-of-given-difference](./problems/1218.longest-arithmetic-subsequence-of-given-difference.md) 🆕
234+
- [1297.maximum-number-of-occurrences-of-a-substring](./problems/1297.maximum-number-of-occurrences-of-a-substring.md) 🆕
234235
- [1310.xor-queries-of-a-subarray](./problems/1310.xor-queries-of-a-subarray.md) 🆕
235236

236237
#### 困难难度
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# 题目地址(1297. 子串的最大出现次数)
2+
3+
https://leetcode-cn.com/problems/maximum-number-of-occurrences-of-a-substring
4+
5+
## 题目描述
6+
7+
```
8+
给你一个字符串 s ,请你返回满足以下条件且出现次数最大的 任意 子串的出现次数:
9+
10+
子串中不同字母的数目必须小于等于 maxLetters 。
11+
子串的长度必须大于等于 minSize 且小于等于 maxSize 。
12+
13+
14+
示例 1:
15+
16+
输入:s = "aababcaab", maxLetters = 2, minSize = 3, maxSize = 4
17+
输出:2
18+
解释:子串 "aab" 在原字符串中出现了 2 次。
19+
它满足所有的要求:2 个不同的字母,长度为 3 (在 minSize 和 maxSize 范围内)。
20+
示例 2:
21+
22+
输入:s = "aaaa", maxLetters = 1, minSize = 3, maxSize = 3
23+
输出:2
24+
解释:子串 "aaa" 在原字符串中出现了 2 次,且它们有重叠部分。
25+
示例 3:
26+
27+
输入:s = "aabcabcab", maxLetters = 2, minSize = 2, maxSize = 3
28+
输出:3
29+
示例 4:
30+
31+
输入:s = "abcde", maxLetters = 2, minSize = 3, maxSize = 3
32+
输出:0
33+
34+
35+
提示:
36+
37+
1 <= s.length <= 10^5
38+
1 <= maxLetters <= 26
39+
1 <= minSize <= maxSize <= min(26, s.length)
40+
s 只包含小写英文字母。
41+
```
42+
43+
## 暴力法
44+
45+
题目给的数据量不是很大,为 1 <= maxLetters <= 26,我们试一下暴力法。
46+
47+
### 思路
48+
49+
暴力法如下:
50+
51+
- 先找出所有满足长度大于等于 minSize 且小于等于 maxSize 的所有子串。(平方的复杂度)
52+
- 对于 maxLetter 满足题意的子串,我们统计其出现次数。时间复杂度为 O(k),其中 k 为子串长度
53+
- 返回最大的出现次数
54+
55+
### 代码
56+
57+
Pythpn Code:
58+
59+
```python
60+
class Solution:
61+
def maxFreq(self, s: str, maxLetters: int, minSize: int, maxSize: int) -> int:
62+
n = len(s)
63+
letters = set()
64+
cnts = dict()
65+
res = 0
66+
for i in range(n - minSize + 1):
67+
length = minSize
68+
while i + length <= n and length <= maxSize:
69+
t = s[i:i + length]
70+
for c in t:
71+
if len(letters) > maxLetters:
72+
break
73+
letters.add(c)
74+
if len(letters) <= maxLetters:
75+
cnts[t] = cnts.get(t, 0) + 1
76+
res = max(res, cnts[t])
77+
letters.clear()
78+
length += 1
79+
return res
80+
```
81+
82+
上述代码会超时。我们来利用剪枝来优化。
83+
84+
## 剪枝
85+
86+
### 思路
87+
88+
还是暴力法的思路,不过我们在此基础上进行一些优化。首先我们需要仔细阅读题目,如果你足够细心或者足够有经验,可能会发现其实题目中 maxSize 没有任何用处,属于干扰信息。
89+
90+
也就是说我们没有必要统计`长度大于等于 minSize 且小于等于 maxSize 的所有子串`,而是统计长度为 minSize 的所有字串即可。原因是,如果一个大于 minSize 长度的字串若是满足条件,那么该子串其中必定有至少一个长度为 minSize 的字串满足条件。因此一个大于 minSize 长度的字串出现了 n 次,那么该子串其中必定有一个长度为 minSize 的子串出现了 n 次。
91+
92+
### 代码
93+
94+
代码支持 Python3,Java:
95+
96+
Python Code:
97+
98+
```python
99+
def maxFreq(self, s: str, maxLetters: int, minSize: int, maxSize: int) -> int:
100+
counter, res = {}, 0
101+
for i in range(0, len(s) - minSize + 1):
102+
sub = s[i : i + minSize]
103+
if len(set(sub)) <= maxLetters:
104+
counter[sub] = counter.get(sub, 0) + 1
105+
res = max(res, counter[sub])
106+
return res;
107+
108+
# @lc code=end
109+
```
110+
111+
Java Code:
112+
113+
```java
114+
public int maxFreq(String s, int maxLetters, int minSize, int maxSize) {
115+
Map<String, Integer> counter = new HashMap<>();
116+
int res = 0;
117+
for (int i = 0; i < s.length() - minSize + 1; i++) {
118+
String substr = s.substring(i, i + minSize);
119+
if (checkNum(substr, maxLetters)) {
120+
int newVal = counter.getOrDefault(substr, 0) + 1;
121+
counter.put(substr, newVal);
122+
res = Math.max(res, newVal);
123+
}
124+
}
125+
return res;
126+
}
127+
public boolean checkNum(String substr, int maxLetters) {
128+
Set<Character> set = new HashSet<>();
129+
for (int i = 0; i < substr.length(); i++)
130+
set.add(substr.charAt(i));
131+
return set.size() <= maxLetters;
132+
}
133+
134+
```
135+
136+
## 关键点解析
137+
138+
- 滑动窗口
139+
- 识别题目干扰信息
140+
- 看题目限制条件,对于本题有用的信息是`1 <= maxLetters <= 26`
141+
142+
## 扩展
143+
144+
我们也可以使用滑动窗口来解决,感兴趣的可以试试看。

0 commit comments

Comments
 (0)