题解 | #DNA序列#

DNA序列

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

描述

题目描述

输入描述:

输入一个string型基因序列,和int型子串的长度

输出描述:

找出GC比例最高的子串,如果有多个则输出第一个的子串

示例

输入:
ACGT
2
输出:
CG
说明:
ACGT长度为2的子串有AC,CG,GT3个,其中AC和GT2个的GC-Ratio都为0.5,CG为1,故输出CG   

知识点:字符串

难度:⭐⭐⭐


题解

方法一:遍历统计

图解

解题思路:

遍历str的所有长度为n的子串,过程中通过两个变量分别保存每次符合的子串的起始索引和CG个数

算法流程

  • 通过三个变量保存状态:maxSum记录GC字母个数,index保存结果子串的起始索引,gcSum记录每个子串中GC长度
  • 从起点索引开始向后遍历n个字符
  • 最后比较gcSum是否大于maxSum,符合则更新状态即可

Java 版本代码如下:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String str = scanner.next();
            int n = scanner.nextInt();
            System.out.println(Solution(str, n));
        }
    }
    
    public static String Solution(String str, int n) {
        // GC字母个数
        int maxSum = 0;
        // 结果子串的起始索引
        int index = 0;
        // 起始索引
        for(int i = 0; i <= str.length() - n; i++) {
            int gcSum = 0;
            // 从起点索引开始向后遍历n个字符
            for(int j = i; j < i + n; j++) {
                if(str.charAt(j) == 'C' || str.charAt(j) == 'G') {
                    gcSum++;
                }
            }
            if(gcSum > maxSum) {
                index = i;
                maxSum = gcSum;
                // 剪枝
                if(gcSum == n) {
                    return str.substring(index, index + n);
                }
            }
        }
        return str.substring(index, index + n);
    }
}

复杂度分析

时间复杂度O(n)O(n), 需要遍历所有子串

空间复杂度O(1)O(1), 只用到了常数空间

方法二:滑动窗口

image-20211209161633296

解题思路

通过滑动窗口的机制实现子串中的统计处理

算法流程

  • 通过左右指针维护一个滑动窗口
  • 每次右指针右移,并判断字符,更新状态变量
  • 窗口缩小时,left左指针右移,同时更新count状态变量

Java 版本代码如下:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String str = scanner.next();
            int n = scanner.nextInt();
            System.out.println(Solution(str, n));
        }
    }
    
    public static String Solution(String str, int n) {
        int left = 0, right = 0;
        int start = 0, count = 0, max = 0;
        while(right < str.length()) {
            char c = str.charAt(right++);
            if(c == 'C' || c == 'G') {
                count++;
            }
            if(count > max){
                max = count;
                start = left;
                // 剪枝
                if(count == n) {
                    return str.substring(start, start + n);
                }
            }
            // 窗口缩小
            if(right - left >= n) {
                char d = str.charAt(left++);
                if(d == 'C' || d == 'G') {
                    count--;
                }
            }
        }
        return str.substring(start, start + n);
    }
}

复杂度分析

时间复杂度O(n)O(n), 滑动窗口需要遍历所有字符

空间复杂度O(1)O(1), 只用到了常数空间

华为机试 文章被收录于专栏

华为机试题解

全部评论
你这个没考虑纯C和纯G的场景,题目要求(DNA序列为 ACGT 的子串有: ACG , CG , CGT 等等,但是没有 AGT , CT 等等)
点赞
送花
回复
分享
发布于 2022-05-08 16:39
为什么都是判断gcSum == n , n是子串的长度啊,题目要求是gc的长度最长,这里不就等于全部都是gc吗?不是很明白这里
点赞
送花
回复
分享
发布于 2022-11-08 11:25 湖南
秋招专场
校招火热招聘中
官网直投
第一个时间复杂度为n * 字符串长度,第二个时间复杂度为字符串长度
点赞
送花
回复
分享
发布于 02-28 21:53 广东

相关推荐

#简历#先说一说我自己的想法,很多人都很排斥苍穹外卖,认为没什么技术点和含金量,但实际上我觉得恰恰相反,苍穹外卖虽然代码本身并不是你自身能力的证明,但是是作为一个新人学习时很好的跳板和原始框架,在这个框架上进行的改进可以很好的辐射到你自己的个人成果上,并作为你和面试官聊天的筹码大多数人的苍穹外卖只写增删改查,千篇一律,吸引不了面试官,所以这才让大家误以为只要是苍穹外卖就不要写进简历里这种误区,但实际上如果你在原有的层面上进行改进,并作为你的项目亮点和面试官介绍,告诉他你的苍穹外卖和别人的有什么不同,增加了哪些技术难点,这才显得你是完全自己理解了这个项目,并且有自己动手实践项目的能力,而不是就看了个课程就以为自己会了,就当成自己的了,如此一来,这反而成为你的加分项苍穹外卖为什么看的人最多,说明它好啊,如果它不好,为什么看的人还这么多,想清楚这个逻辑,我觉得要做的最重要的事,就是如何在原有框架上进行改进提效,比起听其他人的话重新搞一个项目性价比高得多,而且我亲测项目并没有成为我找到工作的阻碍,我投的大厂一大半都给我面试了,而且很多不止一个部门,退一万步说,当你手头没有其他项目的时候,有苍穹外卖总比什么都没有的好很多,不需要因为苍穹外卖有任何心理负担关于简历的任何部分都欢迎大家提意见,十分感谢大家,祝大家找实习+秋招顺利上岸,offer拿到手软#简历中的项目经历要怎么写##我的上岸简历长这样##最后再改一次简历##简历##简历被挂麻了,求建议#
点赞 评论 收藏
转发
10 2 评论
分享
牛客网
牛客企业服务