C ++,multiset,时间复杂度

时间:2017-01-07 04:06:02

标签: c++ time-complexity multiset

#include<bits/stdc++.h>

int main()
{
    int n;
    std::cin>>n;
    char st[n];
    getchar();
    for (int i=0; i<n; ++i)
        st[i]=getchar();
    std::multiset<char> s;
    int pos1=0,pos2=n-1;
    for (char c:st) s.insert(c);
    for (int i=0; i<n; ++i) {
        if (s.count(st[i])==1) {
            pos1=i;
            break;
        } else s.erase(s.find(st[i]));
    }
    for (int i=n-1; i>=0; --i) {
        if (s.count(st[i])==1) {
            pos2=i;
            break;
        } else s.erase(s.find(st[i]));
    }
    std::cout<<pos2-pos1+1;
}

我刚刚将此代码登顶到CodeForces系统,它失败了TL(2s),我不知道为什么,因为n约束是10 ^ 5。我的代码与O(nlogn)一起使用。你们能帮助我吗?谢谢&lt; 3&lt; 3。问题链接在这里:http://codeforces.com/problemset/problem/701/C

1 个答案:

答案 0 :(得分:1)

实际上,您的算法是O(nlogn),但这并不是一个不超过时间限制的保证。请记住,大O复杂度的乘法常数可能太大而无法将其保持在一定的时间限制内。

您只使用multiset来计算每种类型的口袋妖怪。你花了很多时间从那个多重集中删除并重新计算它。你可以比multiset

快得多

1-使用map来保留每种类型的计数并进行更新

2-更好的是,由于口袋妖怪类型以单个字符编码,您可以使用256个元素的数组来跟踪计数。这样你就可以避免&#34; log(n)&#34; multiset(和map)的复杂性。这是您的代码的重构版本,应该运行得更快,而且它是O(n)

int main()
{
    int n;
    std::cin >> n;
    std::vector<char> st(n);
    std::array<int, 256> count; // we could also use a map if we had a bigger set of types...

    // the way you read the input can also be speeded-up,
    // but I want to focus on speeding up the algorithm
    getchar();
    for (int i=0; i<n; ++i) {
        st[i]=getchar(); ++count[st[i]];
    }

    int pos1=0,pos2=n-1;
    for (int i=0; i < n; ++i) {
        if (count[st[i]] == 1) {
            pos1 = i;
            break;
        } else --count[st[i]];
    }
    for (int i=n-1; i>=0; --i) {
        if (s.count(st[i])==1) {
            pos2=i;
            break;
        } else --count[st[i]];
    }
    std::cout<<pos2-pos1+1;
}