(算法)⽕星词典————<BFS解决拓扑排序>

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;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

课堂随笔

感谢支持~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值