当前位置: 首页 > news >正文

茶叶公司网站建设策划书制作展示型网站公司哪家好

茶叶公司网站建设策划书,制作展示型网站公司哪家好,家政的网站怎么做,90设计网图片解密火星词典:拓扑排序的神奇应用 图的构建和拓扑排序基础 大家好!今天我们来解决一道非常有趣且经典的算法题——“火星词典”。这道题表面上看起来是关于字符串比较,但其核心思想却巧妙地指向了图论中的一个重要算法:拓扑排序…

解密火星词典:拓扑排序的神奇应用

图的构建和拓扑排序基础

大家好!今天我们来解决一道非常有趣且经典的算法题——“火星词典”。这道题表面上看起来是关于字符串比较,但其核心思想却巧妙地指向了图论中的一个重要算法:拓扑排序

如果你对拓扑排序还不熟悉,别担心!这篇文章会带你一步步把问题拆解,将一个看似复杂的问题,转化为我们熟悉的模型,并最终用代码实现它。
在这里插入图片描述

问题初探:外星人的排序规则

首先,让我们理解一下题目。我们拿到了一本外星人语言的词典,里面的单词是按照外星字母表的顺序排好的。我们的任务是,根据这些排好序的单词,反推出这个外星字母表的顺序。

举个例子:words = ["wrt", "wrf"]

  1. 这两个单词的前两个字母 wr 都是一样的。
  2. 我们看第一个不同的地方:第三个字母,tf
  3. 因为在词典里,"wrt" 排在 "wrf" 的前面,这告诉我们一个关键信息:在外星字母表中,字母 t 一定排在字母 f 的前面

这就是解题的突破口!词典中相邻两个单词的顺序,为我们提供了字母之间先后关系的线索。

“Aha!”时刻:从先后关系到有向图

tf 前面”,这种“A precedes B”的关系,是不是很像什么?没错,这正是有向图中的一条边!

我们可以把每个出现过的字母看作图中的一个节点(Vertex)
把字母之间的先后关系看作图中的一条有向边(Directed Edge)

tf 前面 => 可以表示为一条从 t 指向 f 的边:t -> f

这条边意味着,在最终的字母表排序中,t 必须出现在 f 的左边。

如果我们把所有单词两两比较,就能得到一系列这样的先后关系,从而构建出一个完整的有向图。例如,对于 words = ["wrt","wrf","er","ett","rftt"]

  1. "wrt" vs "wrf" => t -> f
  2. "wrf" vs "er" => w -> e
  3. "er" vs "ett" => r -> t
  4. "ett" vs "rftt" => e -> r

把这些关系整合起来,我们就得到了一个图:

现在问题就转化成了:找到这个有向图的一个线性序列,使得图中所有的节点都在这个序列中,并且对于图中任意一条从 uv 的边,u 在序列中都出现在 v 的前面。

这,正是拓扑排序的定义!

宏伟蓝图

现在我们有了清晰的思路,可以制定一个三步走的战略:

  1. 数据预处理:遍历所有单词,找出所有出现过的唯一字母,作为我们图中的节点。
  2. 构建有向图:再次遍历单词列表,两两比较相邻的单词,根据第一个不同的字母找到先后关系,并在图中添加有向边。同时,我们还需要记录每个节点的“入度”(即有多少条边指向它)。
  3. 拓扑排序 (Kahn’s 算法)
    • 找到所有入度为 0 的节点,把它们放入一个队列中。这些是没有“先修课程”的字母,可以作为字母表的开头。
    • 当队列不为空时,从中取出一个节点,加入到我们的结果字符串中。
    • 接着,遍历这个节点的所有“邻居”(它指向的节点),并将这些邻居的入度减 1。这相当于“完成了一门先修课”。
    • 如果某个邻居的入度在减 1 后变成了 0,就把它也加入队列。
    • 重复这个过程,直到队列为空。

最后,检查一下结果的合法性。如果结果字符串的长度等于我们找到的唯一字母的数量,说明所有字母都成功排序,拓扑排序完成!否则,说明图中存在环(例如 a->b, b->a),这是一种矛盾的顺序,不存在合法的字母表。

代码实现(你的思路,我的解读)

下面,我们来看看你的代码是如何完美实现这个三步走战略的。

class Solution {
public:string alienOrder(vector<string>& words) {// Step 1: 数据预处理int indegree[26];int kinds = 0; // 用来统计唯一字符的数量for(int i = 0; i < 26; i++) indegree[i] = -1; // -1 表示该字符不存在for(const string& s : words){for(char ch : s){if (indegree[ch - 'a'] == -1) { // 第一次见到这个字符indegree[ch - 'a'] = 0;   // 标记为存在,初始入度为0kinds++;}}}// Step 2: 构建图和计算入度vector<vector<int>> graph(26); // 邻接表表示图for(int i = 0; i < words.size() - 1; i++){string cur = words[i];string next = words[i+1];int minLens = min(cur.size(), next.size());int j = 0;for(; j < minLens; j++) {if(cur[j] != next[j]){// 找到第一对不同字符,添加一条边,并更新入度addEdge(cur[j] - 'a', next[j] - 'a', graph, indegree);break;}}// 处理特殊情况: ["abc", "ab"] 是无效的if(j == minLens && cur.size() > next.size()) return "";}// Step 3: 拓扑排序char queue[26]; // 用一个字符数组模拟队列int l = 0, r = 0;// 将所有入度为0的节点入队for(int i = 0; i < 26; i++){if(indegree[i] == 0) queue[r++] = i + 'a';}stringstream ss; // 用于高效拼接结果字符串while(l < r){char cur = queue[l++];ss << cur;// 遍历当前节点的所有邻居for(int next : getEdgeFrom(cur - 'a', graph)){// 将邻居的入度减1if(--indegree[next] == 0){// 如果入度变为0,则入队queue[r++] = next + 'a';}}}// 最后一步:检查结果是否合法return ss.str().size() == kinds ? ss.str() : "";}// 辅助函数:添加边void addEdge(int u, int v, vector<vector<int>>& V, int indegree[]){V[u].push_back(v);indegree[v]++;}// 辅助函数:获取一个节点的所有出边const vector<int>& getEdgeFrom(int u, const vector<vector<int>>& V){return V[u];}
};

代码解读:

  1. indegree 数组:这个数组一物多用,非常巧妙。初始值 -1 判断字符是否存在,0 或正数则记录其入度。
  2. 建图逻辑:代码准确地找到了相邻单词的第一个不同点来建立依赖关系,并且正确处理了 ["abc", "ab"] 这种前缀关系导致的无效情况。
  3. 模拟队列:你用一个 char 数组和两个指针 l, r 实现了一个简单的队列,这在处理小规模数据时是完全可行的,并且效率很高。
  4. 合法性检查:最后通过比较结果字符串长度和唯一字符数 kinds 来判断是否存在环,这是拓扑排序中检测环的经典方法。
总结

“外星人词典”是一个非常棒的例子,它告诉我们如何将一个具体问题抽象成一个我们熟悉的数学模型(有向图),然后应用经典的算法(拓扑排序)来解决它。这个“建模-求解”的思维过程是算法学习中至关重要的一环。

希望这篇解析能帮助你彻底理解这道题的精髓!Happy coding!

http://www.dtcms.com/a/453382.html

相关文章:

  • 部门定制网站建设公司免费电子版个人简历模板
  • 佛山营销网站建设咨询网站统计分析平台
  • 【工具变量】上市公司气候风险数据集(2011-2023年)
  • nat outbound acl-number address-group group-index 概念及题目
  • 电商网站构建预算方案门户网站html
  • CICD工具选型指南,Jenkins vs Arbess哪一款更好用?
  • 做彩票网站怎么样济南正规网站制作怎么选择
  • C++ 模板、泛型与 auto 关键字
  • 游戏项目 多态练习 超级玛丽demo8
  • 外企 BI 工具选型:从合规到落地
  • 医疗知识普及网站开发网站建立教学
  • Spring Boot中使用线程池来优化程序执行的效率!笔记01
  • 东平网站制作哪家好上海做网站站优云一一十七
  • 玩转ClaudeCode:通过Excel-MCP实现数据清洗并写入Excel
  • LeetCode 2761. 和等于目标值的质数对
  • 网站建设工作落实情况网站买流量是怎么做的
  • 开源 C++ QT QML 开发(九)文件--文本和二进制
  • 添加最新的LSKNet遥感目标检测网络主干
  • 融资网站开发湖南二维码标签品牌
  • 【开源】基于STM32的智能骑行头盔设计
  • 【Python刷力扣hot100】49. Group Anagrams
  • 招聘网站大全专业的企业进销存软件定制
  • 绿色学校网站模板高明网站建设报价
  • Ubuntu 22.04 + Ryu/Mininet:跨越 Python 3.10 依赖“死亡三角”的完美配置指南
  • AI智能体(Agent)大模型入门【6】--编写fasteAPI后端请求接口实现页面聊天
  • 广西 南宁 微信微网站开发虚拟主机使用教程
  • 电子商务网站开发 当当网网站优化关键词怎么做
  • 学习日报 20251007|深度解析:基于 Guava LoadingCache 的优惠券模板缓存设计与实现
  • 什么是MOE?
  • 大模型-扩散模型(Diffusion Model)原理讲解(4