每日一题做题记录,参考官方和三叶的题解 |
题目要求
思路:逆向思维&滑动窗口
修改
k
k
k次搞出来最长的连续段
T
T
T或
F
F
F,逆向思维考虑,找只有
k
k
k个不一样相异的最长段,也就是包含
k
k
k个
F
F
F或
T
T
T的最大窗口长度。
滑动窗口函数getCnt(c)
:
c
n
t
cnt
cnt是区间
[
l
,
r
]
[l,r]
[l,r]里字符
c
c
c的数量,也就是要改的字符的数量。当
c
n
t
>
k
cnt>k
cnt>k,也就是要改的多于要求的,那就移左边界,使窗口范围合法。
Java
class Solution {
String s;
int n, kk;
public int maxConsecutiveAnswers(String answerKey, int k) {
s = answerKey;
n = s.length();
kk = k;
return Math.max(getCnt('T'), getCnt('F'));
}
int getCnt(char c) {
int res = 0;
//滑动窗口
for(int r = 0, l = 0, cnt = 0; r < n; r++) {
if(s.charAt(r) == c)
cnt++;
while(cnt > kk) { //窗口内的字符无法通过kk次变成一样的
if(s.charAt(l) == c)
cnt--; //维护c的个数
l++; //左边界向右移动
}
res = Math.max(res, i - j + 1); //窗口大小
}
return res;
}
}
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
C++
【和java几乎一模一样】
class Solution {
public:
string s;
int n, kk;
int maxConsecutiveAnswers(string answerKey, int k) {
s = answerKey;
n = answerKey.length();
kk = k;
return max(getCnt('T'), getCnt('F'));
}
int getCnt(char c) {
int res = 0;
for(int r = 0, l = 0, cnt = 0; r < n; r++) {
if(s[r] == c)
cnt++;
while(cnt > kk) { //窗口内的字符无法通过kk次变成一样的
if(s[l] == c)
cnt--; //维护c的个数
l++; //左边界向右移动
}
res = max(res, r - l + 1); //窗口大小
}
return res;
}
};
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
Python
前俩写的都一样,搞个略略有点不一样的,把if
判断和维护
c
n
t
cnt
cnt写到一起,其实前边也可以这么搞,甚至前边因为有++
,还可以把自增也放进去。
class Solution:
def maxConsecutiveAnswers(self, answerKey: str, k: int) -> int:
def getCnt(c):
n, res = len(answerKey), 0
r, l, cnt = 0, 0, 0
while r < n:
cnt += answerKey[r] == c
while cnt > k: #窗口内的字符无法通过kk次变成一样的
cnt -= answerKey[l] == c #维护c的个数
l += 1 #左边界向右移动
res = max(res, r - l + 1) #窗口大小
r += 1
return res
return max(getCnt('T'), getCnt('F'))
总结
上了一天课还做pre差点没顾上回来刷题。
对滑动窗口用的不咋熟悉,所以题目做着还有点卡壳。
思路是个逆向的去统计窗口里要改的字符,最开始没有搞懂绕了半天弯子。
【flag时间:打算写个虚拟机网络配置,然后学学dsniff,或许开个secTools系列】
欢迎指正与讨论! |