40环状DNA序列的最小表示法Java版-青训营刷题

问题描述

小C正在研究一种环状的 DNA 结构,它由四种碱基ACGT构成。这种环状结构的特点是可以从任何位置开始读取序列,因此一个长度为 n 的碱基序列可以有 n 种不同的表示方式。小C的任务是从这些表示中找到字典序最小的序列,即该序列的"最小表示"。

例如:碱基序列 ATCA 从不同位置读取可能的表示有 ATCA, TCAA, CAAT, AATC,其中 AATC 是字典序最小的表示。


测试样例

样例1:

输入:dna_sequence = "ATCA"

输出:'AATC'

样例2:

输入:dna_sequence = "CGAGTC"

输出:'AGTCCG'

样例3:

输入:dna_sequence = "TTGAC"

输出:'ACTTG'

代码如下

java 复制代码
public class Main {
    public static String solution(String dna_sequence) {
        // 将 DNA 序列加倍
        String doubledDna = dna_sequence + dna_sequence;
        // 初始化最小顺序为原始 DNA 序列
        String minOrder = dna_sequence;

        // 遍历加倍后的字符串,寻找最小的子串
        for (int i = 1; i < dna_sequence.length(); i++) {
            // 提取从当前索引开始的子串,长度与原始 DNA 序列相同
            String substring = doubledDna.substring(i, i + dna_sequence.length());
            // 如果当前子串比当前最小顺序更小,则更新最小顺序
            if (minOrder.compareTo(substring) >= 0) {
                minOrder = substring;
            }
        }

        return minOrder;
    }

    public static void main(String[] args) {
        // 测试用例
        System.out.println(solution("ATCA").equals("AATC")); // 输出 true
        System.out.println(solution("CGAGTC").equals("AGTCCG")); // 输出 true
        System.out.println(solution("TCATGGAGTGCTCCTGGAGGCTGAGTCCATCTCCAGTAG").equals("AGGCTGAGTCCATCTCCAGTAGTCATGGAGTGCTCCTGG")); // 输出 true
    }
}

代码解释

代码功能概述

这段代码的目的是找到一个 DNA 序列的最小循环子串。具体来说,对于一个给定的 DNA 序列,我们希望找到一个最小的子串,使得这个子串可以通过循环移位得到原始序列。例如,对于 DNA 序列 "ATCA",其最小循环子串是 "AATC",因为 "AATC" 是通过将 "ATCA" 循环左移一位得到的。

代码结构

代码包含一个 Main 类,其中定义了两个方法:

  1. solution 方法:实现核心逻辑,用于找到最小循环子串。

  2. main 方法 :测试 solution 方法的正确性。

代码详细解释

1. solution 方法

java复制

复制代码
public static String solution(String dna_sequence) {
    // 将 DNA 序列加倍
    String doubledDna = dna_sequence + dna_sequence;
    // 初始化最小顺序为原始 DNA 序列
    String minOrder = dna_sequence;

    // 遍历加倍后的字符串,寻找最小的子串
    for (int i = 1; i < dna_sequence.length(); i++) {
        // 提取从当前索引开始的子串,长度与原始 DNA 序列相同
        String substring = doubledDna.substring(i, i + dna_sequence.length());
        // 如果当前子串比当前最小顺序更小,则更新最小顺序
        if (minOrder.compareTo(substring) >= 0) {
            minOrder = substring;
        }
    }

    return minOrder;
}
关键逻辑解释
  1. 加倍 DNA 序列

    java复制

    复制代码
    String doubledDna = dna_sequence + dna_sequence;
    • 为了能够比较所有可能的循环子串,我们将原始 DNA 序列加倍。例如,对于 "ATCA",加倍后的结果是 "ATCAATCA"。这样可以方便地通过索引截取所有可能的循环子串。
  2. 初始化最小顺序

    java复制

    复制代码
    String minOrder = dna_sequence;
    • minOrder 初始化为原始 DNA 序列。这是为了在循环中有一个初始的比较基准。
  3. 循环遍历加倍后的字符串

    java复制

    复制代码
    for (int i = 1; i < dna_sequence.length(); i++) {
        String substring = doubledDna.substring(i, i + dna_sequence.length());
        if (minOrder.compareTo(substring) >= 0) {
            minOrder = substring;
        }
    }
    • 循环范围 :从索引 1 开始,一直到 dna_sequence.length() - 1。这是因为索引 0 对应的子串就是原始 DNA 序列本身。

    • 提取子串 :通过 doubledDna.substring(i, i + dna_sequence.length()) 提取从索引 i 开始的子串,长度与原始 DNA 序列相同。例如,对于 "ATCAATCA",当 i = 1 时,提取的子串是 "TCAATC"

    • 比较子串 :使用 compareTo 方法比较当前子串和 minOrder。如果当前子串更小(或相等),则更新 minOrder

  4. 返回结果

    java复制

    复制代码
    return minOrder;
    • 最终返回找到的最小循环子串。
2. main 方法

java复制

复制代码
public static void main(String[] args) {
    // 测试用例
    System.out.println(solution("ATCA").equals("AATC")); // 输出 true
    System.out.println(solution("CGAGTC").equals("AGTCCG")); // 输出 true
    System.out.println(solution("TCATGGAGTGCTCCTGGAGGCTGAGTCCATCTCCAGTAG").equals("AGGCTGAGTCCATCTCCAGTAGTCATGGAGTGCTCCTGG")); // 输出 true
}
关键逻辑解释
  • 测试用例

    • 使用 solution 方法对几个测试用例进行测试。

    • 使用 equals 方法比较 solution 方法的返回值是否与预期结果一致。

    • 如果一致,输出 true;否则输出 false

总结

这段代码通过加倍 DNA 序列,然后逐个提取子串进行比较,最终找到最小的循环子串。这种方法利用了字符串加倍的技巧,避免了复杂的循环移位操作,使得代码更加简洁高效。

相关推荐
小羊没烦恼!13 小时前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
俊昭喜喜里13 小时前
java中的继承和多态的区别
java
小羊没烦恼!13 小时前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕13 小时前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码13 小时前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖13 小时前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时14 小时前
01-06-A-JVM排查实战详解
java·jvm
伞伞悦读14 小时前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
vipxieliang14 小时前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
C语言小火车15 小时前
C/C++ 为什么需要编译器?
开发语言·c++