二分法 字首和 最長子序列

櫻桃木發表於2020-12-08

牛牛現在有一個長度為len只包含小寫字母‘a’-'z'的字串x,他現在想要一個特殊的子序列,這個子序列的長度為3*n(n為非負整數),子序列的第[1,n]個字母全部為‘a’,子序列的[n+1,2*n]個字母全部為‘b’,子序列的[2*n+1,3*n]個字母全部為‘c’,牛牛想知道最長的符合條件的獨特子序列的長度是多少。

輸入"cbacb" 輸出0

輸入"abaabbcccc" 輸出6

方法一: 二分法

class Solution {
public:
    /**
     * 程式碼中的類名、方法名、引數名已經指定,請勿修改,直接返回方法規定的值即可
     * 
     * @param x string字串 
     * @return int整型
     */
    bool check(int mid, string x){
        int n = x.length();
        int a = 0, b = 0, c = 0;
        for(int i = 0; i < n; ++i){
            if(a < mid){
                if(x[i] == 'a'){
                    ++a;
                }
            }
            else if( b < mid){
                if(x[i] == 'b'){
                    ++b;
                }
            }
            else if(x[i] == 'c'){
                ++c;
            }
        }
        return c >= mid;
    }
    int Maximumlength(string x) {
        int n = x.length();
        int left = 0, right = n, ans = 0;
        while(left <= right){
            int mid = (left + right) / 2;
            if(check(mid, x)){
                ans = mid;
                left = mid + 1;
            }
            else right = mid - 1;
        }
        return ans * 3;
    }
};

方法二:字首和

class Solution {
public:
    /**
     * 程式碼中的類名、方法名、引數名已經指定,請勿修改,直接返回方法規定的值即可
     * 
     * @param x string字串 
     * @return int整型
     */
    int Maximumlength(string x) {
        int n = x.size();
        vector<int> a, c;
        vector<int> presum (n + 1, 0);
        for(int i = 1; i <= n; ++i){
            presum[i] = presum[i - 1];
            if(x[i - 1] == 'a') a.push_back(i - 1);
            if(x[i - 1] == 'b') presum[i]++;
            if(x[i - 1] == 'c') c.push_back(i - 1);
        }
        reverse(c.begin(), c.end());
        int ans = 0;
        for(int i = 0; i < (int)c.size() && i < (int)a.size(); ++i){
            if(c[i] < a[i]) break;
            if(presum[c[i] + 1] - presum[a[i]] < i + 1) break;
            ans++;
        }
        return ans * 3;
    }
};

 

 

 

相關文章