减少检查字符串的子字符串是否是回文的时间复杂度

时间:2017-08-25 11:13:45

标签: c++ string time-complexity palindrome

这是一个检查子串的简单程序,它是一个回文。 它对于长度为1000的字符串工作正常,但在SPOJ上给出TLE错误,长度为100000.如何优化此代码。保存所有子字符串对于如此大的输入不起作用。时间限制是1秒,所以我们最多可以进行10 ^ 6-10 ^ 7次迭代。还有其他方法可以做到。

#include<bits/stdc++.h>

int main()
{
    int t;
    std::cin>>t;
    if(t<1||t>10)
        return 0;
    while(t--)
    {
        std::string s;
        std::cin>>s;
        //std::cout<<s.substr(0,1);
        //std::vector<std::string>s1;
        int n=s.length();
        if(n<1||n>100000)
            return 0;
            int len,mid,k=0,i=0;
        for(i=0;i<n-1;i++)
        {
            for(int j=2;j<=n-i;j++)
            {
                std::string ss=s.substr(i,j);
                //s1.push_back(ss);
            len=ss.length();
            mid=len/2;
            while(k<=mid&&(len-1-k)>=mid&&len>1)
            {
                if(ss[k]!=ss[len-1-k])
                    break;
                k++;
            }
            if(k>mid||(len-1-k)<mid)
            {
                std::cout<<"YES"<<std::endl;
                break;
            }
            }
            if(k>mid||(len-1-k)<mid)
                break;
        }

        if(i==n-1)
            std::cout<<"NO"<<std::endl;
            //for(i=0;i<m;i++)
              //  std::cout<<s1[i]<<std::endl
    }
    return 0;
}

2 个答案:

答案 0 :(得分:0)

我不能完全确定你的功能正在尝试完成...你找到了t回文子串吗?

为了节省内存,而不是将每个子字符串存储在vector中,然后迭代vector以检查回文,为什么不在生成它们时检查子字符串是否是回文?

std::string ss = s.substr(i,j);
// s1.push_back(ss);  // Don't store the substrings
if (palindromic(ss)) {
    std::cout << "YES" << std::endl;
    break;
}

这样可以节省大部分时间,因为您不再总是生成每个可能的子字符串。但是,在最坏的情况下,不能保证更快。

答案 1 :(得分:0)

您假设将所有子字符串保存在另一个向量中并稍后使用相同的O(N ^ 2)方法检查它们将无助于您降低算法的时间复杂度。相反,它也会增加你的内存复杂性。将所有可能的子字符串保存在另一个向量中将占用大量内存。

由于字符串的大小可能最大为10 ^ 5。要检查是否存在任何回文子串,应在 O(NlogN) O(N)时间复杂度内完成,以便在时间限制内通过。为此,我建议你使用两种算法:
1.)后缀数组:链接here
2.)Manacher的算法:链接here