【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;
 }
}
相关推荐
吃好睡好便好8 小时前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
栗子~~9 小时前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
仰泳之鹅9 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
x_yeyue11 小时前
三角形数
笔记·算法·数论·组合数学
Mr. zhihao12 小时前
深入解析redis基本数据结构
数据结构·数据库·redis
念何架构之路12 小时前
Go语言加密算法
数据结构·算法·哈希算法
AI科技星12 小时前
《数学公理体系·第三部·数术几何》(2026 年版)
c语言·开发语言·线性代数·算法·矩阵·量子计算·agi
失去的青春---夕阳下的奔跑12 小时前
560. 和为 K 的子数组
数据结构·算法·leetcode
黎阳之光13 小时前
黎阳之光:以视频孪生重构智慧医院信息化,打造高标项目核心竞争力
大数据·人工智能·物联网·算法·数字孪生
丷丩13 小时前
三级缓存下MVT地图瓦片服务性能优化策略
算法·缓存·性能优化·gis·geoai-up