1. 程式人生 > 其它 >牛客 牛牛的獨特子序列(雙指標/二分查詢)

牛客 牛牛的獨特子序列(雙指標/二分查詢)

技術標籤:LintCode及其他OJ

文章目錄

1. 題目

連結:https://ac.nowcoder.com/acm/contest/9752/B
來源:牛客網

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

示例1
輸入
"cbacb"
返回值 0 說明 沒有符合條件的非空子序列,所以輸出0 示例2 輸入 "abaabbcccc" 返回值 6 說明 最長的符合條件的子序列為"aabbcc",所以輸出6

2. 解題

2.1 雙指標

class Solution {
public:
    /**
     * 程式碼中的類名、方法名、引數名已經指定,請勿修改,直接返回方法規定的值即可
     * 
     * @param x string字串 
     * @return int整型
     */
    // typedef pair<int,int> pii;
    int
Maximumlength(string x) { // write code here string s; for(auto c : x) if(c=='a' || c=='b' || c=='c') s += c; //只需要abc字元 int n = s.size(); if(n < 3) return 0; vector<int> numa(n+1, 0), numb(n+1, 0), numc(n+1, 0);//字首和個數 for
(int i = 1; i <= n; i++) { if(s[i-1] == 'a') { numa[i] = numa[i-1] + 1; numb[i] = numb[i-1]; numc[i] = numc[i-1]; } else if(s[i-1] == 'b') { numa[i] = numa[i-1]; numb[i] = numb[i-1]+1; numc[i] = numc[i-1]; } else { numa[i] = numa[i-1]; numb[i] = numb[i-1]; numc[i] = numc[i-1]+1; } } int ans = 0, a = 0, b= 0, c= 0; int i = 1, j = n; // 貪心,讓 a c,交替變多 while(i <= j) { int MIN = min(a,min(b,c));//數量最少的 if(MIN == a) { a = numa[i++]; } else if(MIN == c) { c = numc[n]-numc[--j]; } else break; b = numb[j]-numb[i-1]; ans = max(ans, 3*min(a,min(b,c))); } return ans; } };

2.2 二分查詢

通用解法

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

我的CSDN部落格地址 https://michael.blog.csdn.net/

長按或掃碼關注我的公眾號(Michael阿明),一起加油、一起學習進步!
Michael阿明