快轉到主要內容
leetcode 424 - Longest Repeating Character Replacement

leetcode 424 - Longest Repeating Character Replacement

·
類別 
Leetcode
標籤 
Java Leetcode Medium String Problem Blind75
Eason Chiu
作者
Eason Chiu
一個不做筆記就容易忘記的工程師
目錄

題目
#

leetcode 424 - Longest Repeating Character Replacement (題目說明請點連結)

題目簡述
#

給一個字串 s 和一個整數 k,請找出可以通過將最多 k 個字符替換為任意字符後,能得到的最長重複字符子字串的長度。
注意:字串只包含大寫英文字母,且替換後的子字串必須全部由相同的字符組成。

範例
#

Example 1:

Input: s = "ABAB", k = 1
Output: 3
Explanation: 可以將一個 'B' 替換為 'A',得到 "AAAB",最長重複字符子字串長度為 3。

Example 2:

Input: s = "AABABBA", k = 1
Output: 4
Explanation: 可以將一個 'B' 替換為 'A',得到 "AAAABBA",最長重複字符子字串長度為 4。

Example 3:

Input: s = "AAAA", k = 2
Output: 4
Explanation: 字串已經全部是 'A',不需要替換,最長重複字符子字串長度為 4。

解題思路
#

這題要求我們找出可以通過最多 k 次替換得到的最長重複字符子字串。我們可以使用滑動窗口(Sliding Window)來解決這個問題,具體方法是維護一個窗口,並統計窗口內每個字符的出現次數。

解法
#

Sliding Window

  1. 使用兩個指針 leftright 來維護滑動窗口
  2. 統計窗口內每個字符的出現次數,並記錄最大出現次數 maxCount
  3. 當窗口大小減去最大出現次數大於 k 時,收縮左指針
  4. 更新答案為窗口大小的最大值

步驟
#

  • 初始化:
    • 創建字符計數陣列 count[26]
    • 設定左指針 left = 0 和答案 ans = 0
    • 設定最大出現次數 maxCount = 0
  • 擴展窗口:
    • 右指針 right 向右移動,統計字符出現次數
    • 更新 maxCount 為當前最大出現次數
  • 收縮窗口:
    • (right - left + 1) - maxCount > k 時,收縮左指針
    • 減少左指針對應字符的計數
  • 更新答案:
    • 更新 ans 為當前窗口大小的最大值
  • 返回結果:
    • 返回 ans

例子說明
#

s = "AABABBA", k = 1

步驟rightleft窗口字符計數maxCount窗口大小需要替換是否收縮答案
初始化-0-[0,0,0,…]000-0
第 1 步00“A”[1,0,0,…]1101
第 2 步10“AA”[2,0,0,…]2202
第 3 步20“AAB”[2,1,0,…]2313
第 4 步30“AABA”[3,1,0,…]3414
第 5 步40“AABAB”[3,2,0,…]3524
第 6 步41“ABAB”[2,2,0,…]2424
第 7 步42“BAB”[1,2,0,…]2314
第 8 步52“BABB”[1,3,0,…]3414
第 9 步62“BABBA”[2,3,0,…]3524

最終結果: 4

完整程式碼
#

java
class Solution {
    public int characterReplacement(String s, int k) {
        // 創建字符計數陣列,統計每個字符的出現次數
        int[] count = new int[26];
        // 左指針、答案、最大出現次數
        int left = 0, ans = 0, maxCount = 0;

        // 右指針向右移動,擴展窗口
        for(int right = 0; right < s.length(); right++){
            // 統計當前字符的出現次數
            int idx = s.charAt(right) - 'A';
            count[idx]++;
            // 更新最大出現次數
            maxCount = Math.max(maxCount, count[idx]);

            // 當窗口大小減去最大出現次數大於 k 時,收縮左指針
            while((right - left + 1) - maxCount > k){
                // 減少左指針對應字符的計數
                count[s.charAt(left) - 'A']--;
                // 左指針向右移動
                left++;
            }

            // 更新答案為當前窗口大小的最大值
            ans = Math.max(ans, right - left + 1);
        }
        
        // 返回最長重複字符子字串的長度
        return ans;
    }
}

時間複雜度
#

  • 時間複雜度O(n),其中 n 是字串的長度
  • 空間複雜度O(1)
    • 使用固定大小的字符計數陣列:O(26) = O(1)
    • 其他變數使用常數空間:O(1)
    • 總空間複雜度為 O(1)

相關文章

leetcode 3 - Longest Substring Without Repeating Characters
類別 
Leetcode
標籤 
Java Leetcode Medium String Problem Blind75
leetcode 5 - Longest Palindromic Substring
類別 
Leetcode
標籤 
Java Leetcode Medium String Problem Blind75
leetcode 57 - Insert Interval
類別 
Leetcode
標籤 
Java Leetcode Medium Array Problem Blind75