如何进一步减少执行时间?

时间:2019-07-13 05:00:55

标签: c++ optimization

我正在尝试比赛的问题。要求如下。

问题:

输入格式:

期望的输出:

我的C ++代码是:-

#include <iostream>
using namespace std;

int main() {

long long n,i,j,k=0,p,q;
cin>>n;//takes size of string//
char s[n];
cin>>s;
cin>>p;//Number of test cases//
for(i=0;i<p;i++)
{
    cin>>q;//takes index to check till//
    for(j=0;j<q-1;j++)
    {
        if(s[j]==s[q-1])//checks if characters are equal//
        {
            k++;//if yes then counts it//
        }
    }
    cout<<k<<endl;
    k=0;//makes cout 0 for next iteration//
}

return 0;

}

代码似乎适用于大多数情况,但是这种情况在某些情况下似乎超出了时间限制。可以做更多的事情来减少时间,在此先感谢您花时间阅读本文。

2 个答案:

答案 0 :(得分:2)

比方说,我们有一个数组cnt,它存储某个字符串i的第i个字符之前的每个字母的出现次数。通过简单地增加相关元素,我们可以轻松地更新此数组以包含第i个字符。因此,我们将迭代更新此数组的字符串,并在第i次迭代中,cnt数组将包含索引i之前的每个字母的计数。

现在,在第i次迭代中,cnt数组中可用于回答查询的信息为cnt[s[i]],因为该信息包含该字符出现的次数索引i前面的字符串部分中的索引i。我们会将这些信息存储在a[i]中,其中a是其他数组。因此,现在a[i]是在i之前的所有位置在索引i处的字母出现的次数,这正是我们希望在索引i处进行查询的次数。因此,我们现在可以使用数组回答查询。

可能的实现:

#include <iostream>
#include <string>
#include <vector>

int main()
{
    //read input
    int n;
    std::string s;
    std::cin >> n >> s;
    //iterate through string maintaining cnt array and adding relevant values to array a
    int cnt[26] = { 0 };
    std::vector<int> a;
    a.reserve(n);
    for (int i = 0; i < n; i++)
    {
        int c = s[i] - 'a';
        a.push_back(cnt[c]);
        cnt[c]++;
    }
    //answer queries
    int q;
    std::cin >> q;
    for (int i = 0; i < q; i++)
    {
        int p;
        std::cin >> p;
        p--;
        std::cout << a[p] << '\n';
    }
}

答案 1 :(得分:0)

首先,此声明:

long long n
cin>>n;//takes size of string//
char s[n];

是非标准的。 g ++支持它,但是我不认为可变大小的数组已经像C语言那样成为C ++标准。而且我怀疑您是否需要long long作为索引类型,除非您扩展到超过20亿个项目。 / p>

更好:

int n;
cin>>n; //takes size of string
vector<char> s(n);

s实际上与数组相同,就像使用[]操作在索引位置对其进行访问一样。

返回解决方案:

使用哈希表,该哈希表在扫描s数组一次时在字符和该字符的出现次数之间进行映射。然后,使用另一个数组来跟踪该索引处的字符到该点出现了多少次。

std::vector<int> positionCount(n);
std::unordered_map<char, int> table;

s中的字符插入到表和positionCount表中,如下所示

for (int i = 0; i < n; i++)
{
    char c = s[i];

    // table[c] is the number of occurrences that "c" was seen in the input array so far
    table[c]++;

    // since table[c] is getting updated as we iterate, 
    // Keep track of the count of the char at position i in a separate array
    positionCount[i] = table[c];
};

然后针对每个测试用例:

for(i=0;i<p;i++)
{
    cin>>q; //takes index to check till

    q--; // off by 1 fix since the array is described as 1..N


    long result = positionCount[q];

    result--; // off by 1 fix again since the output is the preceeding count and doesn't include the character at position q.

    cout << result << endl;

}

由于没有内部for循环,因此上述所有方法在直观上都更快。哈希表的插入和查找与每个数组查找一样为O(1)。

如果您很简单,可以将以上内容简化为这样:

for (int i = 0; i < n; i++)
{
   positionTable[i] = table[s[i]]++;
}

for(i=0;i<p;i++)
{
   cin >> q;
   cout << positionTable[q-1] << endl;
}