一位老師正在出一場由 n 道判斷題構成的考試,每道題的答案為 true (用 'T' 表示)或者 false (用 'F' 表示)。老師想增加學生對自己做出答案的不確定性,方法是最大化有連續相同結果的題數。(也就是連續出現 true 或者連續出現 false)。
給你一個字串 answerKey,其中 answerKey[i] 是第 i 個問題的正確結果。除此以外,還給你一個整數 k,表示你能進行以下操作的最多次數:
每次操作中,將問題的正確答案改為 'T' 或者 'F'(也就是將 answerKey[i] 改為 'T' 或者 'F')。請你返回在不超過 k 次操作的情況下,最大連續 'T' 或者 'F' 的數目。
示例 1:
輸入:answerKey = "TTFF", k = 2
輸出:4
解釋:我們可以將兩個 'F' 都變為 'T',得到 answerKey = "TTTT"。
總共有四個連續的 'T'。
示例 2:
輸入:answerKey = "TFFT", k = 1
輸出:3
解釋:我們可以將最前面的 'T' 換成 'F',得到 answerKey = "FFFT"。
或者,我們可以將第二個 'T' 換成 'F',得到 answerKey = "TFFF"。
兩種情況下,都有三個連續的 'F'。
示例 3:
輸入:answerKey = "TTFTTFTT", k = 1
輸出:5
解釋:我們可以將第一個 'F' 換成 'T',得到 answerKey = "TTTTTFTT"。
或者我們可以將第二個 'F' 換成 'T',得到 answerKey = "TTFTTTTT"。
兩種情況下,都有五個連續的 'T'。
提示:
n == answerKey.length
1 <= n <= 5 * 10^4
answerKey[i] 要麼是 'T',要麼是 'F'
1 <= k <= n
題解:
字元長度最大值分為兩種情況:
- 把 'T' 改成 'F'的
- 把 ’F‘ 改成 'T'的
兩種情況取 max
這題可以用滑動視窗來維護一個視窗, 使視窗中要改變的字元數 sum 不超過 k 個, 同時使視窗中的元素儘可能多
滑動視窗, 不多解釋了
ac程式碼👇, 程式碼請從第二個函式maxConsecutiveAnswers開始看
class Solution {
public:
int solve(string s, int k, char c)
{
int res = 0; // sum是要改變的字元數
for (int l = 0, r = 0, sum = 0; r < s.size(); r ++)
{
if (s[r] != c) sum ++; // 每次往前移動一位, 如果是要改變的字元 sum ++, 不是的話 不加, 儘可能保證視窗長度比較大
while (sum > k) // 保證 sum 一定 <= k
{
if (s[l] != c) sum --;
l ++;
}
res = max(res, r - l + 1); // r 和 l 是視窗的左右閉區間, 求視窗中元素的個數 r - l + 1
}
return res;
}
int maxConsecutiveAnswers(string answerKey, int k) {
// 改變'T'的 和 改變'F'的取最大值
int res = max(solve(answerKey, k, 'T'), solve(answerKey, k, 'F'));
return res;
}
};
總結
滑動視窗演算法是一種用於解決子陣列或子串問題的有效技巧.
常見型別:
-
固定長度的子陣列/子串:
- 問題:找到固定長度的子陣列或子串,並求其某些特徵(如最大或最小值、平均值等)。
- 例子:給定一個陣列和一個整數k,找到長度為k的子陣列的最大平均值。
-
可變長度的子陣列/子串:
- 問題:找到可變長度的子陣列或子串,使其滿足某些條件(如和等於某個值、包含某些字元等)。
- 例子:給定一個陣列,找到和等於某個值的最長子陣列。
-
最長或最短的子陣列/子串:
- 問題:找到滿足某些條件的最長或最短子陣列或子串。
- 例子:給定一個字串和一個整數k,找到包含最多k個不同字元的最長子串。
本題屬於第三種, 滿足某個條件的最長子陣列
滑動視窗演算法通常用於需要在線性時間內解決子陣列或子串問題的場景。這些問題的特徵通常包括尋找具有特定屬性的最長或最短子陣列/子串,以及滿足某些條件的子陣列/子串。這種技術透過動態調整視窗的大小,使得演算法能在高效的時間複雜度內找到問題的解。
覺得寫的不錯的話, 點個贊吧~