一道简单的面试题

昨天晚上参加了一个模拟考试,做到简答题时被其中的一个编程题卡住了。最后也没有写出来,不过一觉醒来之后,发现其实也并不难。
题个大概意思如下:DNA序列由A C G T四个元素构成,如ACGCGTA。所谓逆序是指类似上面:GC GA CA这样的片段。一段DNA序列的逆序度是指序列中逆序的个数。
题目要求:现给定一DNA序列,求出该序列的逆序度,要求时间复杂度为 O(N) ,N为序列长度。
分析:最简单的方法无非就是对每一个元素进行遍历,但这样的话时间复杂度是 O( N2) ,是不符合要求的。
所以必须从其他角度考虑,可以发现。对于某个元素,只需要关注有多少个和它为逆序的元素出现在它之前就行。如在index为6(index从0开始)的地方为元素C,我们只需要关注在6之前G,T出现了多少次就行。
这样的话只需要遍历一次,该序列的逆序度就求出来了。时间复杂度正好为 O(N)
我的解法如下:

#include <cstdio>
int search_number(const char *padna){
    //C作为A C G T的计数器 
    int c[4]={0,0,0,0},num=0;

    for(int i=0;padna[i]!='\0';i++){
        switch(padna[i]){
            case 'A':
                c[0]++;
                num+=c[1]+c[2]+c[3];
                break;
            case 'C':
                c[1]++;
                num+=c[2]+c[3];
                break;
            case 'G':
                    c[2]++;
                    num+=c[3];
                    break;
            case 'T':
                c[3]++;
                break;
            default:
                break;
        }
    }
    return num;
}
int main(void){
    const char *padna="TGCA";
    int number=search_number(padna);
    printf("%d\n",number);
    return 0;   
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值