C语言/数据结构字符串题解:找出DNA序列中未配对的独特序列——排序+遍历(O(nlogn))

问题描述

小明是一位古生物研究员,最近在分析一批远古生物化石的DNA序列。每个DNA序列由一系列字符组成(仅包含'A', 'C', 'G', 'T'),他发现这些序列中,除了一个序列外,其他所有序列都恰好有另一个完全相同的序列与之配对(表示来自同一个生物个体)。完全相同指的是字符串内容完全一致。

现在需要你帮助小明找出那个没有配对的独特DNA序列,以确定其所属的生物种类。

要求:

  1. 设计一个算法,在O(n)的时间复杂度内找出独特的DNA序列,其中n是序列的数量。
  2. 尽量减少额外空间的使用,以体现算法的优化能力。

测试样例

样例1:

输入:sequences = ["ACGT", "ACGT", "GCTA", "GCTA", "TTAA", "TTAA", "CGAT"] 输出:"CGAT" 解释:序列"ACGT"出现两次(配对),"GCTA"出现两次(配对),"TTAA"出现两次(配对),"CGAT"只出现一次(没有配对)。

样例2:

输入:sequences = ["A", "A", "C", "C", "G"] 输出:"G" 解释:序列"A"出现两次(配对),"C"出现两次(配对),"G"只出现一次(没有配对)。

样例3:

输入:sequences = ["TT", "TT", "AA", "CC", "CC", "AA", "GG"] 输出:"GG" 解释:序列"TT"出现两次(配对),"AA"出现两次(配对),"CC"出现两次(配对),"GG"只出现一次(没有配对)。

约束条件

  • 1 ≤ sequences.length ≤ 1001(且为奇数)
  • 1 ≤ sequencesi.length ≤ 100
  • sequencesi 仅包含字符 'A', 'C', 'G', 'T'
  • 除了一个序列外,其他每个序列都恰好出现两次

程序代码

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

// 比较函数:按字典序

int cmp(const void* a, const void* b) {

return strcmp(*(char**)a, *(char**)b);

}

char* findUniqueDNA(char** sequences, int sequencesSize) {

// 复制指针数组(避免修改原数组)

char** sorted = (char**)malloc(sequencesSize * sizeof(char*));

for (int i = 0; i < sequencesSize; i++) {

sortedi = sequencesi;

}

// 排序

qsort(sorted, sequencesSize, sizeof(char*), cmp);

// 遍历找独特字符串

char* result = NULL;

int i = 0;

while (i < sequencesSize) {

if (i + 1 < sequencesSize && strcmp(sortedi, sortedi + 1) == 0) {

// 成对,跳过两个

i += 2;

} else {

// 独特字符串

result = sortedi;

break;

}

}

free(sorted);

return result;

}

int main() {

char* sequences1\[\] = {"ACGT", "ACGT", "GCTA", "GCTA", "TTAA", "TTAA", "CGAT"};

int size1 = 7;

printf("%s\n", findUniqueDNA(sequences1, size1)); // CGAT

char* sequences2\[\] = {"A", "A", "C", "C", "G"};

int size2 = 5;

printf("%s\n", findUniqueDNA(sequences2, size2)); // G

char* sequences3\[\] = {"TT", "TT", "AA", "CC", "CC", "AA", "GG"};

int size3 = 7;

printf("%s\n", findUniqueDNA(sequences3, size3)); // GG

return 0;

}

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 比较函数:按字典序
int cmp(const void* a, const void* b) {
    return strcmp(*(char**)a, *(char**)b);
}

char* findUniqueDNA(char** sequences, int sequencesSize) {
    // 复制指针数组(避免修改原数组)
    char** sorted = (char**)malloc(sequencesSize * sizeof(char*));
    for (int i = 0; i < sequencesSize; i++) {
        sorted[i] = sequences[i];
    }
    
    // 排序
    qsort(sorted, sequencesSize, sizeof(char*), cmp);
    
    // 遍历找独特字符串
    char* result = NULL;
    int i = 0;
    while (i < sequencesSize) {
        if (i + 1 < sequencesSize && strcmp(sorted[i], sorted[i + 1]) == 0) {
            // 成对,跳过两个
            i += 2;
        } else {
            // 独特字符串
            result = sorted[i];
            break;
        }
    }
    
    free(sorted);
    return result;
}

int main() {
    char* sequences1[] = {"ACGT", "ACGT", "GCTA", "GCTA", "TTAA", "TTAA", "CGAT"};
    int size1 = 7;
    printf("%s\n", findUniqueDNA(sequences1, size1));  // CGAT
    
    char* sequences2[] = {"A", "A", "C", "C", "G"};
    int size2 = 5;
    printf("%s\n", findUniqueDNA(sequences2, size2));  // G
    
    char* sequences3[] = {"TT", "TT", "AA", "CC", "CC", "AA", "GG"};
    int size3 = 7;
    printf("%s\n", findUniqueDNA(sequences3, size3));  // GG
    
    return 0;
}

运行结果

相关推荐
Navigator_Z1 小时前
LeetCode //C - 1248. Count Number of Nice Subarrays
c语言·算法·leetcode
是隼人2 小时前
buuctf-pwn picoctf_2018_shellcode(ret2shellcode)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
wzdark2 小时前
基于链表的内存池设计与内存复用机制4
java·数据结构·链表
潜创微科技2 小时前
IT6520:USB-C 转 MIPI 高集成控制器,DP 1.4a 转 MIPI 单芯片搞定 4K120 显示
c语言·开发语言·低延迟·掌机·联阳
白色的北极熊3 小时前
字符转 ASCII 码
c语言
BizzZ_4 小时前
算法(1)——双指针
数据结构
Doubbbbbbble云4 小时前
内存碎片化对数据结构操作性能的影响研究4
数据结构
xiangyun616 小时前
【408数据结构 03】线性表与顺序表:C++手写SeqList
开发语言·数据结构·c++
君科程序定做7 小时前
用 IDL 处理高分一号(GF-1 / GF-1B/C/D)数据
c语言·开发语言