牛客 牛牛的獨特子序列(雙指標/二分查詢)
阿新 • • 發佈:2020-12-10
技術標籤: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阿明),一起加油、一起學習進步!