【BFS 解决拓扑排序】3. ⽕星词典(hard)

BFS 解决拓扑排序

拓扑排序简介

3. ⽕星词典(hard)

  1. 题⽬链接:LCR 114. ⽕星词典
  2. 题⽬描述:
    现有⼀种使⽤英语字⺟的外星⽂语⾔,这⻔语⾔的字⺟顺序与英语顺序不同。
    给定⼀个字符串列表 words ,作为这⻔语⾔的词典, words 中的字符串已经 按这⻔新语⾔的字⺟顺序进⾏了排序 。
    请你根据该词典还原出此语⾔中已知的字⺟顺序,并 按字⺟递增顺序 排列。若不存在合法字⺟顺序,返回 "" 。若存在多种可能的合法字⺟顺序,返回其中 任意⼀种 顺序即可。
    字符串 s 字典顺序⼩于 字符串 t 有两种情况:
    • 在第⼀个不同字⺟处,如果 s 中的字⺟在这⻔外星语⾔的字⺟顺序中位于 t 中字⺟之前,那么 s 的字典顺序⼩于 t 。
    • 如果前⾯ min(s.length, t.length) 字⺟都相同,那么 s.length < t.length时, s 的字典顺序也⼩于 t 。
    ⽰例 1:
    输⼊:words = ["wrt","wrf","er","ett","rftt"]
    输出:"wertf"
    ⽰例 2:
    输⼊:words = ["z","x"]
    输出:"zx"
    ⽰例 3:
    输⼊:words = ["z","x","z"]
    输出:""
    解释:不存在合法字⺟顺序,因此返回 "" 。
    提⽰:
    ◦ 1 <= words.length <= 100
    ◦ 1 <= words[i].length <= 100
    ◦ words[i] 仅由⼩写英⽂字⺟组成
  3. 解法:

    算法思路:
    将题意搞清楚之后,这道题就变成了判断有向图时候有环,可以⽤拓扑排序解决。
    如何搜集信息(如何建图):
    a. 两层 for 循环枚举出所有的两个字符串的组合;
    b. 然后利⽤指针,根据字典序规则找出信息。

算法代码:

java 复制代码
class Solution
{
 Map<Character, Set<Character>> edges = new HashMap<>(); // 邻接表
 Map<Character, Integer> in = new HashMap<>(); // 统计每个节点的⼊度
 boolean check;
 public String alienOrder(String[] words)
 {
	 // 1. 初始化⼊度哈希表 + 建图
	 for(String s : words)
	 {
		 for(int i = 0; i < s.length(); i++)
		 {
			 char ch = s.charAt(i);
			 in.put(ch, 0);
		 }
	 }
	 int n = words.length;
	 for(int i = 0; i < n; i++)
	 {
		 for(int j = i + 1; j < n; j++)
		 {
			 add(words[i], words[j]);
			 if(check == true) return "";
		 }
	 }
	 // 2. 拓扑排序
	 Queue<Character> q = new LinkedList<>();
	 for(char ch : in.keySet())
	 {
	 	if(in.get(ch) == 0) q.add(ch);
	 }
	 StringBuffer ret = new StringBuffer();
	 while(!q.isEmpty())
	 {
		 char t = q.poll();
		 ret.append(t);
		 if(!edges.containsKey(t)) continue;
		 for(char ch : edges.get(t))
		 {
			 in.put(ch, in.get(ch) - 1);
			 if(in.get(ch) == 0) q.add(ch);
		 }
	 }
	 // 3. 判断
	 for(char ch : in.keySet())
	 {
	 	if(in.get(ch) != 0) return "";
	 }
 	 return ret.toString();
 }
 public void add(String s1, String s2)
 {
	 int n = Math.min(s1.length(), s2.length());
	 int i = 0;
	 for( ; i < n; i++)
	 {
		 char c1 = s1.charAt(i), c2 = s2.charAt(i);
		 if(c1 != c2)
		 {
			 // c1 -> c2
			 if(!edges.containsKey(c1))
			 {
			 	edges.put(c1, new HashSet<>());
			 }
			 if(!edges.get(c1).contains(c2))
			 {
				 edges.get(c1).add(c2);
				 in.put(c2, in.get(c2) + 1);
			 }
			 break;
		 }
	 }
	 if(i == s2.length() && i < s1.length()) check = true;
 }
}
相关推荐
董董灿是个攻城狮10 小时前
AI视觉连载8:传统 CV 之边缘检测
算法
雨中飘荡的记忆13 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
AI软著研究员17 小时前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish18 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
颜酱19 小时前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
曲幽1 天前
FastAPI分布式系统实战:拆解分布式系统中常见问题及解决方案
redis·python·fastapi·web·httpx·lock·asyncio
地平线开发者1 天前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶
董董灿是个攻城狮1 天前
大模型连载2:初步认识 tokenizer 的过程
算法
地平线开发者1 天前
地平线 VP 接口工程实践(一):hbVPRoiResize 接口功能、使用约束与典型问题总结
算法·自动驾驶
罗西的思考1 天前
AI Agent框架探秘:拆解 OpenHands(10)--- Runtime
人工智能·算法·机器学习