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

问题描述

小C正在研究一种环状的 DNA 结构,它由四种碱基A、C、G、T构成。这种环状结构的特点是可以从任何位置开始读取序列,因此一个长度为 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 序列,然后逐个提取子串进行比较,最终找到最小的循环子串。这种方法利用了字符串加倍的技巧,避免了复杂的循环移位操作,使得代码更加简洁高效。

相关推荐
1024奇点6 小时前
【仓颉语言入门 · 第二篇 第 22 课】
开发语言·ide·开源
Warren2Lynch7 小时前
C4 模型详解:利用 Visual Paradigm 可视化软件架构的综合指南
开发语言·uml
天河归来7 小时前
第三方接口不稳定,如何让核心任务继续完成
java·大数据
Knight_AL7 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
FRing038 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
by209999 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
砚底藏山河9 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
IT召唤狮9 小时前
开源企业级零信任项目Pangolin,零信任能挡住PHP核弹漏洞吗?
开发语言·开源·php
知已难寻9 小时前
03 · OpenStack的计算管理 Nova
运维·服务器·开发语言·云原生·云计算·openstack·开源软件
Rover Ramble9 小时前
C++ 用互斥锁实现读写锁
开发语言·c++