图论做题笔记:bfs

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

笔记:

这道题是真抽象,对字符串进行bfs,这里的思路是:直接对字符串去处理不要讲单个字符单独处理。首先建立一个处理队列,将start加入其中,此时队列中的元素表示未处理的元素,接下来记录当前层的大小,遍历当前层的元素(只有start一个),接着对字符串进行处理,这里我们创建一个数组来存储字符可变化的样子(也就是方向数组),从当前处理的字符串的头开始向后遍历,一一替换当前遍历到的位置,如果替换后的字符串可以在bank中找到并且没有被访问过我们就将其加入que的第二层,在遍历完当前层元素后step++代表变换元素的次数。

注意:

(1)当我们向队列加入一个元素后,立即将其标记为已访问。

(2)将vector类型的bank数组改为set数组更好处理:

在一个set数组中查找元素是否存在:set.count(目标)

cpp 复制代码
class Solution {
public:
    int minMutation(string startGene, string endGene, vector<string>& bank) {
        unordered_set<string> visited;
        unordered_set<string> bank_set(bank.begin(), bank.end());
        char keys[4] = {'A', 'C', 'G', 'T'};
        int step = 0;
        queue<string> que;
        que.push(startGene);
        visited.insert(startGene);
        while(!que.empty()){
            int size = que.size();
            for(int i = 0; i < size; i++){
                string cur = que.front();
                que.pop();
                if(cur == endGene){
                    return step;
                }
                for(int j = 0; j < cur.size(); j++){
                    for(int k = 0; k < 4; k++){
                        string next = cur;
                        next[j] = keys[k];
                        if(bank_set.count(next) && !visited.count(next)){
                            que.push(next);
                            visited.insert(next);
                        }
                    }
                }
            }
            step++;
        }
        return -1;
    }
};
相关推荐
一隅论数智4 小时前
OWL(Web Ontology Language)介绍与使用举例(二)
大数据·经验分享·笔记·学习·自然语言处理·学习方法·政务
sunoo-2298 小时前
【嵌入式Linux驱动学习】Day1-Day2 全流程梳理:环境搭建→U-Boot→内核→根文件系统→驱动基础
linux·运维·驱动开发·笔记·学习·阿里云·恩智浦
垆边人似月.8 小时前
城市连通性(200分 / 并查集)
数据结构·算法·图论
by209999 小时前
list:迭代器与资源管理实现的综合叙述(下)
数据结构·c++·笔记·list
wdfk_prog9 小时前
LWIP教程 03:从 `low_level_input()` 到 `pbuf_free()`——`pbuf` 的数据视图、Chain 与引用计数
运维·网络·笔记·学习
yi01110 小时前
Leetcode 49 用 “身份证‘‘巧解
人工智能·笔记·python·算法·leetcode·哈希表
ouynagda10 小时前
嵌入式Linux i.MX6ULL系统移植学习笔记
linux·笔记·学习
yi01110 小时前
DAY22: LeetCode 733:图像渲染——从二维网格开始理解 DFS 和 BFS
数据结构·笔记·python·算法·leetcode·深度优先·宽度优先
sbjdhjd10 小时前
智能体开始“动手”之后:OpenAI越权事件、Anthropic算力资本化与开放权重模型竞逐 | AI与SI行业日报整理(9月29日—10月6日)
大数据·人工智能·经验分享·笔记·ai·chatgpt·开源
上位机妹子11 小时前
从零理解 EF Core:用 Minimal API 给「工作项看板」建模(小白笔记)
笔记