题解 | #abb#

abb

http://www.nowcoder.com/practice/0a8bbf8b9b5b4280957849ef4f240f07

开始时设想使用前缀和的方法,建立一个sum数组,其中sum.at(i)保存的是前i项中abb的个数。
按顺序遍历字符串,使用一个二重循环,对每一个字符都统计其在之前出现的次数以及其他字符出现的位置,按照C(2,n)的组合数计算规则可以发现C(2,1), C(2,2), ..., C(2,n)组成的数列满足差后等差,且差后的等差数列公差为1。按照这一性质,即可得到下面的处理方法。
对每一个字符c,从该字符的前一个字符向前遍历,每遇到一个与c相同的字符,count++,每遇到一个与c不同的字符,使sum.at(i)+=count。

这种做法时间复杂度为O(n^2),比较高。所以在提交后第8个用例处超时,由于用例输入数据过多,无法判断是循环内部逻辑导致超时,还是单纯的时间复杂度过高导致超时。这里暂且认为是时间复杂度过高导致超时,转而寻找时间复杂度更低的做法。

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

using namespace std;

int main(){
    int n;
    string str;
    cin >> n;
    cin >> str;
    vector<long long> sum(n);
    for(int i = 0;i < n;i++){
        if(i < 2){
            sum.at(i) = 0;
        }
        else{
            int count = 0;
            sum.at(i) = sum.at(i - 1);
            for(int j = i - 1;j > - 1;j--){
                if(str[j] == str[i]){
                    count++;
                }
                else{
                    if(count > 0){
                        sum.at(i) += count; 
                    }
                }
            }
        }
    }
    cout << sum.at(n - 1);
    return 0;
}



参考了别人的做法后发现,维护一个字母出现次数的后缀和数组会更为合理,时间复杂度也更低。
建立一个后缀和数组sum,使sum.at(i).at(j)表示下标i~n-1中字母表第j个字母出现的次数。
有了sum后,就可以根据该数组,来逐个计算字符串中每一个字符与后面字母组成的叠词次数。计算方法如同前面所说,使用组合数的计算公式c(2,N)即可。

这种方法虽然看似使用了二重循环,但由于内层循环的循环次数是固定的常数26,所以时间复杂度为O(n)。由于使用了辅助的后缀和数组,空间复杂度为O(n)。

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

using namespace std;

int main(){
    int n;
    string str;
    cin >> n;
    cin >> str;
    vector<int> temp(26, 0);
    vector<vector<int>> sum(n, temp);
    long long res = 0;
    sum.at(n - 1).at(str[n - 1] - 'a')++;
    for(int i = n - 2;i > -1;i--){
        for(int j = 0;j < 26;j++){
            sum.at(i).at(j) = sum.at(i + 1).at(j);
        }
        sum.at(i).at(str[i] - 'a')++;
    }
    for(int i = 0;i < n;i++){
        for(int j = 0;j < 26;j++){
            if(j != str[i] - 'a'){
                res += sum.at(i).at(j) * (sum.at(i).at(j) - 1) / 2;
            }
        }
    }
     cout << res;
    return 0;
}
全部评论

相关推荐

10-17 16:48
已编辑
南方科技大学 图像识别
记录一下找工作的感受吧。鼠鼠硕士阶段搞的图像处理,用了深度学习比较成熟、简单的模型,技能点主要在科研上研二下学期准备找工作,先投AI、机器学习的暑期实习,没有结果。当时不想投开发,觉得太累了。后面找不到工作,就转开发了。但是八股不会,刷题不精,挂了好多笔试面试。在一个线下宣讲会获得了一个小科技公司的日常实习机会。我的实习公司,70%是应届生,共同话题很多。我问了算法部门刚入职的同事,一位同事硕士阶段和我的成果差不多。他们毕业院校一般,觉得算法很难,之后想换工作。我也有几个985硕科班算法的朋友,他们去找工作🈚压力。我等凡人不跟他们竞争了。工位旁还有几位java开发工程师,我需要他们提供接口给我,大概也了解了他们的工作内容。一个同事说弄懂java虚拟机最重要。而我看那些知识点觉得很枯燥,我想我还是稍喜欢现在的工作,主要画画ui。鼠鼠也蛮喜欢科研,但是科研压力很大,想出好文章有时违背本心。而且鼠鼠方向和工业界联系不紧密,挣不了大钱。如果出国的话,🇺🇸现在环境比较糟糕,签证很难弄。好几个朋友想出国申博,还没结果。祝他们好运吧,我就不想继续卷了。同学院其他找工作的女生同学,只能找营销,产品经理之类的岗位,她们不是很喜欢。我是本科有一些开发经历,加上学历过关,才能转码的。男生稍微好一点,但是专业原因找工作也是有一些困难。大概就记录到这里吧,供大家参考,尤其是和我一样不上不下背景,正在纠结的朋友。截图随便配的,这家公司投了之后懒得做测评,今天收到面试邀请,我懒得去了。位置在惠州,觉得很远。u1s1,开发的工作真的好多,不论老家,还是惠州这种城市,还是深圳,都很多。
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务