字符串 APPAPT 中包含了两个单词 PAT,其中第一个 PAT 是第 2 位( P ),第 4 位( A ),第 6 位( T );第二个 PAT 是第 3 位( P ),第 4 位( A ),第 6 位( T )。
现给定字符串,问一共可以形成多少个 PAT?
输入格式:
输入只有一行,包含一个字符串,长度不超过105,只包含 P、A、T 三种字母。
输出格式:
在一行中输出给定字符串中包含多少个 PAT。由于结果可能比较大,只输出对 1000000007 取余数的结果。
输入样例:
APPAPT
输出样例:
2
思路:
三重循环完成计数。
代码:
#include<stdio.h>
#include<string.h>
int main(){
char s[100001];
scanf("%s",s);
int len=strlen(s);
long cnt=0;
for(int i=0;i<len-2;++i){
if(s[i]=='P'){
for(int j=i+1;j<len-1;++j){
if(s[j]=='A'){
for(int k=j+1;k<len;++k){
if(s[k]=='T'){
++cnt;
}
}
}
}
}
}
printf("%ld",cnt%1000000007);
}
出现的问题:
测试点2、3、4运行超时,当前算法时间复杂度为O(n3),所以需要优化,或者改用其他方法。
第一次修改:
既然是要找出字符串中有多少个PAT,那么如果找到了A,PAT的个数即等于A左侧P的个数乘上A右侧T的个数。这样的话针对A做一次循环即可求解,时间复杂度为O(n)。
#include<stdio.h>
int main(){
char ch,s[100001];
int cnt_p=0,cnt_t=0,len=0;
for(int i=0;(ch=getchar())!='\n';++i,++len){
s[i]=ch;
if(ch=='T'){
++cnt_t;
}
}
long cnt=0;
for(int i=0;i<len;++i){
if(s[i]!='A'){
if(s[i]=='P'){
++cnt_p;
}
else{
--cnt_t;
}
}
else{
cnt+=cnt_p*cnt_t;
}
}
printf("%ld",cnt%1000000007);
return 0;
}