1. 题⽬链接:LCR114.⽕星词典
2. 题⽬描述:
3. 解法:
算法思路:
将题意搞清楚之后,这道题就变成了判断有向图时候有环,可以⽤拓扑排序解决。
如何搜集信息(如何建图):
a. 两层for循环枚举出所有的两个字符串的组合;
b. 然后利⽤指针,根据字典序规则找出信息。
C++算法代码:
class Solution
{
public:
unordered_map<char,unordered_set<char>>edges; //邻接表
unordered_map<char,int>in; //记录入度
bool check=false; //字母顺序错误标识
//初始化邻接表
void Add_edges(string a,string b)
{
int n=min(a.size(),b.size());
int i=0;
for(;i<n;i++)
{
if(a[i]!=b[i])
{
if(!edges.count(a[i])||!edges[a[i]].count(b[i]))
{
edges[a[i]].insert(b[i]);
in[b[i]]++;
}
break;
}
}
//判断字母顺序是否合法
if(i==b.size()&&i<a.size())
{
check=true;
}
}
string alienOrder(vector<string>& words)
{
//初始化入度表
for(auto& s : words)
{
for(auto ch : s)
{
in[ch] = 0;
}
}
//获取数据
for(int i=0;i<words.size();i++)
{
for(int j=i+1;j<words.size();j++)
{
Add_edges(words[i],words[j]);
//字母顺序错误时返回空字符串
if(check)
{
return "";
}
}
}
//将入度为0的点加入队列
queue<char>q;
string answer; //答案
for(auto& [a, b] : in)
{
if(b == 0)
{
q.push(a);
}
}
//拓扑排序
while(q.size())
{
char t=q.front();
q.pop();
answer+=t;
//与之连接的点入度减一
for(auto key:edges[t])
{
in[key]--;
if(in[key]==0)
{
q.push(key);
}
}
}
//判断拓扑排序是否能够完成
for (auto& [a, b] : in)
{
if (b != 0)
{
return "";
}
}
return answer;
}
};
Java算法代码:
class Solution
{
Map<Character, Set<Character>> edges = new HashMap<>(); // 邻接表
Map<Character, Integer> in = new HashMap<>(); // 统计每个节点的⼊度
boolean check;
public String alienOrder(String[] words)
1
2
3
4
5
6
7 {
// 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;
}
}