Algorithm 按字母顺序排序的子字符串计数
给定长度为N的字符串S。字符串S由小写英文字母组成。我们需要计算S的子串被排序了多少 给定字符串S,我们需要计算S的已排序子字符串的数量 如果s[i],字符串s按字典顺序排序≤ s[i+1]其中1≤ 我≤ N-1(考虑基于1的索引)。 示例:让字符串S=“bba”那么答案是4 解释:“bba”的子字符串是:b,b,a,bb,ba,bba 在这6个子串中,有4个('b','b','a'和'bb')子串被排序。所以答案是4Algorithm 按字母顺序排序的子字符串计数,algorithm,Algorithm,给定长度为N的字符串S。字符串S由小写英文字母组成。我们需要计算S的子串被排序了多少 给定字符串S,我们需要计算S的已排序子字符串的数量 如果s[i],字符串s按字典顺序排序≤ s[i+1]其中1≤ 我≤ N-1(考虑基于1的索引)。 示例:让字符串S=“bba”那么答案是4 解释:“bba”的子字符串是:b,b,a,bb,ba,bba 在这6个子串中,有4个('b','b','a'和'bb')子串被排序。所以答案是4 我目前的解决方案并不比暴力好多少。即检查每个子字符串,然后检查其是否已排序。
我目前的解决方案并不比暴力好多少。即检查每个子字符串,然后检查其是否已排序。但字符串长度可能是1000000,所以O(N^2)方法不起作用。那么,对于这个问题有什么更好的解决方案呢?制作两个索引-左索引和右索引。将它们都设置为字符串的第一个符号索引。当
s[右]时增加右≤ s[右+1]
当下一个符号违反顺序时,您有子字符串
ss=s[Left..Right]
,ss的所有子字符串也被排序。通过ss长度查找其编号:
k = Right - Left + 1
你有k个一字符的子字符串,k-1个两字符的子字符串。。。和1个k长度的子串
N = 1 + 2 +... + k = k * (k + 1) / 2
将N添加到SUSBSTRING总数中,向左和向右移动到(右+1)并继续。\include
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
ll sum(ll n)
{
return (n*(n+1))/2;
}
int main()
{
int test;
cin>>test;
while(test--)
{
int l;
cin>>l;
string s;
cin>>s;
ll ans=0, length=1;
for(int i=1;i<s.size();i++)
{
//increment till it is not violating lexicographical order
if(s[i]>=s[i-1])
length++;
else//store current length sum to ans and start again by setting length to one
{
ans+=sum(length);
length=1;
}
}
ans+=sum(length);
cout<<ans<<endl;
}
return 0;
}
使用名称空间std;
#定义ll long long int
ll sum(ll n)
{
返回(n*(n+1))/2;
}
int main()
{
智力测验;
cin>>试验;
而(测试--)
{
int l;
cin>>l;
字符串s;
cin>>s;
ll ans=0,长度=1;
对于(int i=1;i=s[i-1])
长度++;
else//将当前长度总和存储到ans,然后通过将长度设置为1重新开始
{
ans+=总和(长度);
长度=1;
}
}
ans+=总和(长度);
库特