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

相关推荐
无名之逆12 分钟前
Hyperlane:高性能 Rust HTTP 服务器框架评测
服务器·开发语言·windows·后端·http·rust
M malloc16 分钟前
【C++奇遇记】C++中的进阶知识(继承(一))
java·jvm·c++
跨境卫士-小汪25 分钟前
关税核爆72小时!跨境矩阵防御战紧急打响
开发语言·php
褚翾澜29 分钟前
Bash语言的社区交流
开发语言·后端·golang
独好紫罗兰42 分钟前
洛谷题单3-P4956 [COCI 2017 2018 #6] Davor-python-流程图重构
开发语言·python·算法
侧耳倾听1111 小时前
单元测试之mockito
java·单元测试
CHPCWWHSU1 小时前
vulkanscenegraph显示倾斜模型(5.6)-vsg::RenderGraph的创建
开发语言·javascript·ecmascript
苹果酱05671 小时前
SpringCloud第二篇:注册中心Eureka
java·vue.js·spring boot·mysql·课程设计
圈圈编码1 小时前
WebSocket
java·网络·spring boot·websocket·网络协议·spring
szuaudi1 小时前
SpringMVC实现text/event-stream(SSE)
java·spring