LeetCode题练习与总结:最小基因变化--433

一、题目描述

基因序列可以表示为一条由 8 个字符组成的字符串,其中每个字符都是 'A''C''G' 和 'T' 之一。

假设我们需要调查从基因序列 start 变为 end 所发生的基因变化。一次基因变化就意味着这个基因序列中的一个字符发生了变化。

  • 例如,"AACCGGTT" --> "AACCGGTA" 就是一次基因变化。

另有一个基因库 bank 记录了所有有效的基因变化,只有基因库中的基因才是有效的基因序列。(变化后的基因必须位于基因库 bank 中)

给你两个基因序列 start 和 end ,以及一个基因库 bank ,请你找出并返回能够使 start 变化为 end 所需的最少变化次数。如果无法完成此基因变化,返回 -1 。

注意:起始基因序列 start 默认是有效的,但是它并不一定会出现在基因库中。

示例 1:

输入:start = "AACCGGTT", end = "AACCGGTA", bank = ["AACCGGTA"]
输出:1

示例 2:

输入:start = "AACCGGTT", end = "AAACGGTA", bank = ["AACCGGTA","AACCGCTA","AAACGGTA"]
输出:2

示例 3:

输入:start = "AAAAACCC", end = "AACCCCCC", bank = ["AAAACCCC","AAACCCCC","AACCCCCC"]
输出:3

提示:

  • start.length == 8
  • end.length == 8
  • 0 <= bank.length <= 10
  • bank[i].length == 8
  • startend 和 bank[i] 仅由字符 ['A', 'C', 'G', 'T'] 组成

二、解题思路

这个问题可以看作是一个无向图的最短路径问题,其中每个基因序列是一个节点,如果两个基因序列之间只有一个字符不同,那么这两个节点之间有一条边。我们的目标是找到从起点基因序列到终点基因序列的最短路径。

以下是解题步骤:

  • 创建一个集合(或使用布尔数组)来记录基因库中哪些基因序列已经被使用过,以避免重复访问。
  • 使用一个队列来进行广度优先搜索(BFS)。初始时,将起点基因序列放入队列中。
  • 在队列不为空的情况下,进行以下操作:
    • 从队列中取出一个基因序列。
    • 如果这个基因序列与终点基因序列相同,返回当前的变化次数。
    • 否则,遍历基因库中的每个基因序列,检查是否只有一个字符不同,并且该基因序列没有被使用过。如果是,将其加入队列,并标记为已使用。
  • 如果队列为空还没有找到终点基因序列,返回 -1。

三、具体代码

import java.util.*;public class Solution {public int minMutation(String start, String end, String[] bank) {// 使用集合来记录已经使用过的基因序列Set<String> visited = new HashSet<>();// 使用队列进行广度优先搜索Queue<String> queue = new LinkedList<>();// 初始化队列和访问集合queue.offer(start);visited.add(start);// 变化次数int steps = 0;while (!queue.isEmpty()) {int size = queue.size();// 遍历当前层的所有节点for (int i = 0; i < size; i++) {String current = queue.poll();// 如果当前节点与终点相同,返回变化次数if (current.equals(end)) {return steps;}// 遍历基因库中的每个基因序列for (String gene : bank) {// 如果基因序列没有被使用过,并且只有一个字符不同if (!visited.contains(gene) && isMutation(current, gene)) {queue.offer(gene);visited.add(gene);}}}// 增加变化次数steps++;}// 如果无法完成变化,返回 -1return -1;}// 检查两个基因序列是否只有一个字符不同private boolean isMutation(String start, String end) {int diff = 0;for (int i = 0; i < start.length(); i++) {if (start.charAt(i) != end.charAt(i)) {diff++;if (diff > 1) {return false;}}}return diff == 1;}
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 初始化阶段,将起始基因序列 start 加入队列,这一步的时间复杂度是 O(1)。

  • 在广度优先搜索(BFS)过程中,我们遍历队列中的每个元素,并对每个元素检查基因库中的所有基因序列。假设基因库的大小为 n,那么在每层BFS中,我们需要检查 n 个基因序列,并且对于每个基因序列,我们执行 isMutation 方法来检查是否只有一个字符不同,isMutation 方法的时间复杂度是 O(8),因为每个基因序列的长度是固定的 8。

  • BFS 可能会遍历所有 n 个基因序列,因为最坏情况下每个基因序列都可能被加入到队列中。因此,队列的大小最多可能是 n。

综合以上分析,总的时间复杂度是 O(n^2 * 8),可以简化为 O(n^2),因为 8 是一个常数。

2. 空间复杂度
  • visited 集合用于存储已经访问过的基因序列,最坏情况下需要存储 n 个基因序列,因此空间复杂度是 O(n)。

  • 队列 queue 在最坏情况下可能包含所有 n 个基因序列,因此空间复杂度也是 O(n)。

综合以上分析,总的空间复杂度是 O(n) + O(n),可以简化为 O(n),因为两个 O(n) 是同阶的。

五、总结知识点

  • 面向对象编程(OOP)

    • 类定义(public class Solution)。
    • 方法定义(public int minMutation(...) 和 private boolean isMutation(...))。
  • 数据结构

    • 集合(Set<String>):用于存储已经访问过的基因序列,确保不会重复访问。
    • 队列(Queue<String>):用于实现广度优先搜索(BFS)。
  • 算法

    • 广度优先搜索(BFS):用于在无向图中找到从起点到终点的最短路径。
    • 字符串比较:用于判断两个基因序列是否只有一个字符不同。
  • 字符串操作

    • 使用 charAt(int index) 方法获取字符串中指定位置的字符。
    • 使用 equals(Object anObject) 方法比较两个字符串是否相等。
  • 控制结构

    • 循环结构:for 循环用于遍历队列中的元素和字符串中的字符。
    • 条件语句:if 语句用于检查条件是否满足,并据此执行不同的操作。
  • 集合操作

    • 使用 add(E e) 方法向集合中添加元素。
    • 使用 contains(Object o) 方法检查集合中是否包含特定的元素。
  • 队列操作

    • 使用 offer(E e) 方法向队列中添加元素。
    • 使用 poll() 方法从队列中取出并移除头部元素。
    • 使用 size() 方法获取队列中的元素数量。
  • 错误处理

    • 如果无法从起始基因序列变换到目标基因序列,则返回 -1

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/481101.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IP与“谷子”齐飞,阅文“乘势而上”?

爆火的“谷子经济”&#xff0c;又捧出一只“潜力股”。 近日&#xff0c;阅文集团股价持续上涨&#xff0c;5日累计涨幅达13.20%。这其中&#xff0c;周三股价一度大涨约15%至29.15港元&#xff0c;强势突破20日、30日、120日等多根均线&#xff0c;市值突破280亿港元关口。 …

EXCEL截取某一列从第一个字符开始到特定字符结束的字符串到新的一列

使用EXCEL中的公式进行特定截取 假设列A是一组产品的编码&#xff0c;我们需要的数据是“-”之前的字段。 我们需要在B1单元格输入公式“LEFT(A1,SEARCH("-",A1)-1)”然后选中B1至B4单元格&#xff0c;按“CTRLD”向下填充&#xff0c;就可以得出其它几行“-”之前的…

重塑视频新语言,让每一帧都焕发新生——Video-Retalking,开启数字人沉浸式交流新纪元!

模型简介 Video-Retalking 模型是一种基于深度学习的视频再谈话技术&#xff0c;它通过分析视频中的音频和图像信息&#xff0c;实现视频角色口型、表情乃至肢体动作的精准控制与合成。这一技术的实现依赖于强大的技术架构和核心算法&#xff0c;特别是生成对抗网络&#xff0…

多头注意力机制:从原理到应用的全面解析

目录 什么是多头注意力机制&#xff1f; 原理解析 1. 注意力机制的核心公式 2. 多头注意力的扩展 为什么使用多头注意力&#xff1f; 实际应用 1. Transformer中的应用 2. NLP任务 3. 计算机视觉任务 PyTorch 实现示例 总结 近年来&#xff0c;“多头注意力机制&…

力扣637. 二叉树的层平均值

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 提示&#xff1a; 树中节点数量在 [1, 104] 范围内-231 < Node.val < 231 - 1 代码&#xff1a; /*** Definition for a binary tree node.* stru…

Opencv+ROS实现摄像头读取处理画面信息

一、工具 ubuntu18.04 ROSopencv2 编译器&#xff1a;Visual Studio Code 二、原理 图像信息 ROS数据形式&#xff1a;sensor_msgs::Image OpenCV数据形式&#xff1a;cv:Mat 通过cv_bridge()函数进行ROS向opencv转换 cv_bridge是在ROS图像消息和OpenCV图像之间进行转…

Perforce SAST专家详解:自动驾驶汽车的安全与技术挑战,Klocwork、Helix QAC等静态代码分析成必备合规性工具

自动驾驶汽车安全吗&#xff1f;现代汽车的软件包含1亿多行代码&#xff0c;支持许多不同的功能&#xff0c;如巡航控制、速度辅助和泊车摄像头。而且&#xff0c;这些嵌入式系统中的代码只会越来越复杂。 随着未来汽车的互联程度越来越高&#xff0c;这一趋势还将继续。汽车越…

架构-微服务-服务配置

文章目录 前言一、配置中心介绍1. 什么是配置中心2. 解决方案 二、Nacos Config入门三、Nacos Config深入1. 配置动态刷新2. 配置共享 四、nacos服务配置的核心概念 前言 服务配置--Nacos Config‌ 微服务架构下关于配置文件的一些问题&#xff1a; 配置文件相对分散。在一个…

攻防世界GFSJ1193 cat_theory

题目编号&#xff1a;GFSJ1193 附件下载后是一个jpg文件和一个sage文件&#xff08;python&#xff09;&#xff1a; 1. 分析图片&#xff08;.jpg文件&#xff09; 这个交换图展示的是一个加密系统的 同态加密 性质&#xff0c;其核心思想是&#xff1a;加密前的操作与加密后…

qt QGraphicsPolygonItem详解

1、概述 QGraphicsPolygonItem是Qt框架中QGraphicsItem的一个子类&#xff0c;它提供了一个可以添加到QGraphicsScene中的多边形项。通过QGraphicsPolygonItem&#xff0c;你可以定义和显示一个多边形&#xff0c;包括其填充颜色、边框样式等属性。QGraphicsPolygonItem支持各…

ubuntu20配置mysql注意事项

目录 一、mysql安装 二、初始化配置密码 三、配置文件的位置 四、常用的mysql命令 五、踩坑以及解决方法 一、mysql安装 1.更新apt源 sudo apt update 2.安装mysql服务 sudo apt-get install mysql-server 3.初始化配置 sudo mysql_secure_installation 4.配置项 VALI…

USB-C取电协议芯片与LDR6328的功能解析

随着科技的发展&#xff0c;USB-C接口已经逐渐成为各种智能设备的标准充电和数据传输接口。其正反可插、高速传输、以及强大的电力传输能力&#xff0c;为用户带来了极大的便利。而USB-C取电协议芯片&#xff0c;则是实现这些功能的关键组件之一。本文将详细介绍USB-C取电协议芯…

ceph手动部署

ceph手动部署 一、 节点规划 主机名IP地址角色ceph01.example.com172.18.0.10/24mon、mgr、osd、mds、rgwceph02.example.com172.18.0.20/24mon、mgr、osd、mds、rgwceph03.example.com172.18.0.30/24mon、mgr、osd、mds、rgw 操作系统版本&#xff1a; Rocky Linux release …

Vue:使用 KeepAlive 缓存切换掉的 component

一、内置特殊元素 不是组件 <component>、<slot> 和 <template> 具有类似组件的特性&#xff0c;也是模板语法的一部分。但它们并非真正的组件&#xff0c;同时在模板编译期间会被编译掉。因此&#xff0c;它们通常在模板中用小写字母书写。 1.1 <compone…

nginx 升级http 到 http2

同步发布于我的网站 &#x1f680; 背景介绍准备工作配置过程遇到的问题及解决方法验证升级总结参考资料 背景介绍 HTTP/2 是 HTTP 协议的最新版本&#xff0c;相比 HTTP/1.1&#xff0c;它带来了多项重要的改进&#xff0c;包括多路复用、头部压缩和服务端推送。这些特性可…

FFmpeg 推流给 FreeSWITCH

FFmpeg 推流&#xff0c;貌似不难&#xff0c;网上有很多资料, 接到一个任务&#xff0c;推流给 FreeSWITCH&#xff0c;最开始以为很容易&#xff0c; 实则不然&#xff0c;FreeSWITCH uuid_debug_media <uuid>&#xff0c; 一直没人任何反应 仔细一查&#xff0c;Fr…

【趣味】斗破苍穹修炼文字游戏HTML,CSS,JS

目录 图片展示 游戏功能 扩展功能 完整代码 实现一个简单的斗破苍穹修炼文字游戏&#xff0c;你可以使用HTML、CSS和JavaScript结合来构建游戏的界面和逻辑。以下是一个简化版的游戏框架示例&#xff0c;其中包含玩家修炼的过程、增加修炼进度和显示经验值的基本功能。 图片…

解决 java -jar 报错:xxx.jar 中没有主清单属性

问题复现 在使用 java -jar xxx.jar 命令运行 Java 应用程序时&#xff0c;遇到了以下错误&#xff1a; xxx.jar 中没有主清单属性这个错误表示 JAR 文件缺少必要的启动信息&#xff0c;Java 虚拟机无法找到应用程序的入口点。本文将介绍该错误的原因以及如何通过修改 pom.xm…

家校通小程序实战教程04教师管理

目录 1 创建数据源2 搭建管理后台3 搭建查询条件4 功能测试总结 我们上一篇介绍了如何将学生加入班级&#xff0c;学生加入之后就需要教师加入了。教师分为任课老师和班主任&#xff0c;班主任相当于一个班级的管理员&#xff0c;日常可以发布各种任务&#xff0c;发布接龙&…

VUE前端实现天爱滑块验证码--详细教程

第一步&#xff1a; Git地址&#xff1a;tianai-captcha-demo: 滑块验证码demo 找到目录 src/main/resources/static,拷贝 static 并改名为 tac 即可。 第二步&#xff1a; 将改为 tac 的文件&#xff0c;放进项目根目录中&#xff0c;如下图&#xff1a; 第三步&#xff1…