最大長反復の[Leetcode周レース149] 1156文字列

最大長反復の最長繰り返し部分文字列を単一の文字列の場合1156スワップ

説明

文字列内のすべての文字が同じである場合、その文字列は単一の文字列が繰り返されています。
あなたの文字列を付けtext、1つのまたは2つの文字が何もしないでいる入れ替えることができ、その後、いくつかの単一文字の繰り返し部分文字列を取得します。最長の部分文字列の長さを返します。

  • 例1:

    入力:テキスト=「アベバ」
    出力:3
    説明:我々は最後の「A」と、または最初の「A」と最後の「b」を置き換えるために最初の「b」を置き換えることができます。次いで、文字の最長のサブストリングを繰り返すと、その長さは、「AAA」である3

  • 例2:

    入力:テキスト=「aaabaaa」
    出力:6
    説明:最後の「A」(または最初の「A」)を使用して「b」を置き換える、私たちは、最長繰り返し文字部分文字列「AAA」を取得し、その長さは6であります

  • 例3:

    入力:テキスト= "aaabbaaa"
    出力:4

  • 例4:

    入力:テキスト=「AAAAA」
    出力:5
    説明:無交換は、最も長い部分文字列が文字を繰り返されていない「AAA」、5の長さを

  • 例5:

    入力:テキスト= "ABCDEF"
    出力:1

  • ヒント:
    1 <= text.length <= 20000
    テキストのみ小文字の英文字。

考え

ウィンドウスライディング考え
左右マージン、および拡張することができた「ウィンドウ」、維持するために
、この問題は、開始位置の「ウィンドウ」を右に移動し、
1)元の文字位置、+ 1に等しく、
2)に等しくありません、その後、何もありません右側に見る為替同じ文字がと何もありませんフォールトトレラントスペース(旧1は、使用0の後、)

  • 注:特別の事情
    「AABA」この交換は、右の文字を持っていますが、(等しいが許容できない)、その後フォールトトレラント文字、結果は文字の周波数を超える計算します

コードの実装

class Solution {
    public int maxRepOpt1(String text) {
        if (null == text | text.length() <= 0) return 0;
        
        int len = text.length();
        char[] chs = text.toCharArray();
        //cnt 字符串中所出现字符的频数
        int[] cnt = new int[30];
        // type 字符串中字符种类
        int type = 0;
        
        for (char c : chs) {
            int ind=c-'a';
            if (cnt[ind]==0) type++;
            cnt[ind]++;
        }
        // 字符串中字符没有重复
        if (type == len) return 1;
        // 字符串中字符全部单字符重复
        if (type == 1) return len;
        
        // size 重复子串最大长度/滑动窗口最大长度
        int size = 0;
        for (int i = 0; i < len;) {
            char begin = chs[i];
            // now 当前重复子串最大长度
            // time 容错余裕 可以结合字符频数提前判断 
            //      cnt[begin-'a']==1 --> time=0 没有可以交换字符 容错余裕为0
            // next 下一个窗口开始位置(因为i++ 会导致有些计算冗余 可以直接从容错位置开始)
            int now = 0, time = 1, next=i+1;
            // 滑动窗口向右扩展
            for (int j = i; j < len; j++) {
                // 相等
                if (chs[j]==begin) now++;
                // 不相等 但有容错和可交换字符
                else if ((time-- > 0) && (cnt[begin-'a']-now >= 1)) {now++; next=j;}
                else break;
            }

            // 特殊情况 计算长度必定不大于字符频数
            now = now > cnt[begin-'a'] ? cnt[begin-'a'] : now;
            // 比较原最大长度与当前长度
            size = now > size ? now : size;
            i = next;
        }
        
        return size;
    }
}

おすすめ

転載: www.cnblogs.com/slowbirdoflsh/p/11367818.html