Algorithm 按字母顺序排序的子字符串计数

Algorithm 按字母顺序排序的子字符串计数,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 我目前的解决方案并不比暴力好多少。即检查每个子字符串,然后检查其是否已排序。

给定长度为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+=总和(长度); 库特