leetcode_[python/C++]_424_Longest Repeating Character Replacement

題目鏈接
【題目】
Given a string that consists of only uppercase English letters, you can replace any letter in the string with another letter at most k times. Find the length of a longest substring containing all repeating letters you can get after performing the above operations.


Note:
Both the string’s length and k will not exceed 104.

Example 1:

Input:
s = “ABAB”, k = 2

Output:
4

Explanation:
Replace the two ‘A’s with two ‘B’s or vice versa.


Example 2:

Input:
s = “AABABBA”, k = 1

Output:
4

Explanation:
Replace the one ‘A’ in the middle with ‘B’ and form “AABBBBA”.
The substring “BBBB” has the longest repeating letters, which is 4.
Subscribe to see which companies asked this question


【分析】
這道題主要是爲了分享一種很不錯的解法,叫做滑窗算法,類似我們計算機網絡中的發送數據包的滑動窗口移動。
算法思想:
即定義end和begin指針,end -begin即爲窗體的長度,始終維護一個窗體,要保證該窗體中:窗體長度 - 最多字母個數 > k,也就是維護窗體中除了個數最多的字符外,其他字符總數不超過k。窗體長度即爲最多變換k次之後,最長的相同字母字符串。

class Solution {
public:
    int characterReplacement(string s, int k) {
        int size = s.size();
        vector<int> count(26,0);
        int begin = 0, maxlen = 0, ans = 0;
        for(int end=0;end<size;end++){
            maxlen = max(maxlen,++count[s[end]-'A']);
            while(end - begin + 1 - maxlen > k) count[s[begin++] - 'A']--;//相當於count[s[begin] - 'A']--;  begin ++;
            ans = max(ans,  end - begin + 1);
        }
        return ans;
    }
};

python寫法

class Solution(object):
    def characterReplacement(self,s, k):
        """
        :type s: str
        :type k: int
        :rtype: int
        """
        from math import *
        size = len(s)
        count = [0]*26
        begin = 0
        maxlen = 0
        ans = 0
        for end in range(size):
            count[ord(s[end])-ord('A')] = count[ord(s[end])-ord('A')] + 1
            maxlen = max(maxlen,count[ord(s[end])-ord('A')])
            while end - begin + 1 - maxlen > k:
                count[ord(s[begin])-ord('A')] = count[ord(s[begin])-ord('A')] - 1
                begin = begin + 1
            ans = max(ans,end - begin + 1)
        return ans

discuss中有一種利用collections.counters()的做法,很強

class Solution(object):
    def characterReplacement(self, s, k):
        res = lo = 0
        counts = collections.Counter()
        for hi in range(len(s)):
            counts[s[hi]] += 1
            max_char_n = counts.most_common(1)[0][1]
            while (hi - lo - max_char_n + 1 > k):
                counts[s[lo]] -= 1
                lo += 1
            res = max(res, hi - lo + 1)
        return res

這道題一開始看錯題目了,以爲k是指能改變一種字母多少次,就寫了下面這種代碼,有點粗糙但是符合這種要求的解法

int characterReplacement(string s, int k) {

        set<char> sets;
        int size = s.size();
        for(int i=0;i<size;i++){
            sets.insert(s[i]);
        }
        char chr;
        set<char>::iterator iter;
        char ans_chr;
        int begin_index = 0;
        int end_index = 0;
        int max = -100000;
        for(iter = sets.begin();iter!= sets.end();iter++){
            chr = *iter;
            vector<int> dp(size,0);
            vector<int> first(sets.size(),0);
            int num[124];
            memset(num,0,sizeof(num));

            for(int i=1;i<size;i++){
                if(num[s[i]] == 0) first[s[i]] = i;
                if(s[i]==chr){
                    dp[i] = dp[i-1];
                    if(i==1 && s[i]!=s[i-1]) dp[i] = 1;
                }
                else{
                    if(num[s[i]] < k){
                        num[s[i]]++;
                        dp[i] = dp[i-1];
                    }
                    else{
                        if(first[s[i]] == 0){
                            dp[i] = i;
                            memset(num,0,sizeof(num));
                            first[s[i]] = i;
                        }
                        else{
                            dp[i] = first[s[i]]+1;
                            memset(num,0,sizeof(num));
                            for(int j = first[s[i]]+1;j<=i;j++){
                                if(num[s[j]] == 0){
                                    first[s[j]] = j;
                                }
                                num[s[j]]++;
                            }
                        }


                    }
                }
            }
            for(int i=0;i<size;i++){
                if(i-dp[i]>max){
                    begin_index = dp[i];
                    end_index = i;
                    max = i - dp[i];
                    ans_chr = chr;
                }
            }

        }
        return max+1;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章