题解 | #DNA序列#

DNA序列

http://www.nowcoder.com/practice/e8480ed7501640709354db1cc4ffd42a

题目分析

  1. 题目给出我们一个由A/G/C/T四种字母组成的字符串,并且给出了一个目标子串的固定长度值
  2. 题目希望我们在给定长度下锁定一个子串中,输出从左到右数G和C出现的比率最高的第一个给定长度的的子串

方法一:暴力截取子串并计数

  • 实现思路
    • 我们直接用python切片的方式,遍历给出的字符串来获得一个个目标子串

    • 然后对目标字串进行G和C的计数

    • 如果G和C的数量占比高,则更新可能的输出结果

    • 直到遍历结束为止,输出第一个G和C含量最高的子串


def solution(s, k):
    if k >= len(s):                                # 处理特殊情况
        print(s)
        return
    mx = 0
    res = ""
    for i in range(len(s)-k):                      # 遍历字符串,找到子串的起点
        sub = s[i:i+k]                             # 获得子串
        count = sub.count('C') + sub.count('G')    # 计算CG的含量
        if count > mx:                             # 根据CG含量更新最大值
            mx = count
            res = sub
    print(res)
    return

while True:
    try:
        s = input()
        k = int(input())
        solution(s, k)
    except:
        break

复杂度分析

  • 时间复杂度:O(k(nk))O(k(n-k)),其中n是给出字符串的长度,k是截取的子字符串长度。由于只遍历一次字符串,且遍历的起点只有n-k个,所以代价为O(nk)O(n-k),但是对于每个子串都需要遍历一轮数出所有的G和C的数量,因此最终代价为O(k(nk))O(k(n-k))
  • 空间复杂度:O(k)O(k),每轮存储子串长度的字符串变量空间开销

方法二:滑动窗口优化计数

  • 实现思路
    • 在方法一的基础上,我们在字串的G和C含量统计上进行优化
    • 我们通过控制窗口访问的元素来调整计数结果
    • 如果左侧的元素退出窗口,右侧有新的元素进入窗口,判断是否是C或G来调整计数的结果
    • 这样优化了内层对于子串的遍历开销

alt


def solution(s, k):
    if k >= len(s):                                # 处理特殊情况
        print(s)
        return
    sub = s[:k]
    cur = mx = sub.count('C') + sub.count('G')
    res = sub
    for i in range(1, len(s)-k):                          # 遍历字符串,找到子串的起点
        sub = s[i:i+k]
        if s[i - 1] == 'C' or s[i - 1] == 'G':            # 如果左侧刚刚退出一个字符C或G,则计数器-1
            cur -= 1
        if s[i + k - 1] == 'C' or s[i + k - 1] == 'G':    # 如果右侧刚刚进入一个字符C或G,则计数器+1
            cur += 1
        # print(sub, cur, sub.count('G')+sub.count('C'))
        if cur > mx:                                      # 是否要更新新的结果
            res = sub
            mx = cur
    print(res)
    return

while True:
    try:
        s = input()
        k = int(input())
        solution(s, k)
    except:
        break

复杂度分析

  • 时间复杂度:O(n)O(n),由于首先初始化cur变量时候,一次子串的遍历计数时间为O(k)O(k),然后在循环过程中遍历的代价又是O(nk)O(n-k),因此最终的时间代价为O(n)O(n)
  • 空间复杂度:O(k)O(k),每轮存储子串长度的字符串变量空间开销
全部评论
range(1, len(s)-k + 1)吧
1 回复 分享
发布于 2023-10-09 21:36 广东

相关推荐

我是没经验的毕业生,这啥情况啊会不会是hr在刷kpi
JamesGosli...:字节boss属于是群发了,我都快入职字节了,其他部门还在和我boss打招呼
点赞 评论 收藏
分享
07-09 19:25
门头沟学院 Java
这是要把每一个投校招的都开盒吗?
26届之耻将大局逆转:裁人的时候一次性追回餐费
点赞 评论 收藏
分享
06-10 21:15
门头沟学院 Java
宁阿:好多这种没🧠的公司,他们估计都不知道毕业的人不能给安排实习岗
实习吐槽大会
点赞 评论 收藏
分享
叶扰云倾:进度更新,现在阿里云面完3面了,感觉3面答得还行,基本都答上了,自己熟悉的地方也说的比较细致,但感觉面试官有点心不在焉不知道是不是不想要我了,求阿里收留,我直接秒到岗当阿里孝子,学校那边的房子都退租了,下学期都不回学校,全职猛猛实习半年。这种条件还不诱人吗难道 然后现在约到了字节的一面和淘天的复活赛,外加猿辅导。华为笔试完没动静。 美团那边之前投了个base广州的,把我流程卡麻了,应该是不怎么招人,我直接简历挂了,现在进了一个正常的后端流程,还在筛选,不知道还有没有hc。
点赞 评论 收藏
分享
评论
11
2
分享

创作者周榜

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