老卫带你学---leetcode刷题(269. 火星词典)

269. 火星词典

问题:

现有一种使用字母的全新语言,这门语言的字母顺序与英语顺序不同。

假设,您并不知道其中字母之间的先后顺序。但是,会收到词典中获得一个 不为空的 单词列表。因为是从词典中获得的,所以该单词列表内的单词已经 按这门新语言的字母顺序进行了排序。

您需要根据这个输入的列表,还原出此语言中已知的字母顺序。

示例 1:

输入:
[
  "wrt",
  "wrf",
  "er",
  "ett",
  "rftt"
]
输出: "wertf"

示例 2:

输入:
[
  "z",
  "x"
]
输出: "zx"

示例 3:

输入:
[
  "z",
  "x",
  "z"
] 
输出: "" 

解释: 此顺序是非法的,因此返回 “”。

提示:

你可以默认输入的全部都是小写字母
若给定的顺序是不合法的,则返回空字符串即可
若存在多种可能的合法字母顺序,请返回其中任意一种顺序即可

解决:

class Solution:
    def alienOrder(self, words: List[str]) -> str:
        # 每个字母代表图的一个顶点
        # 邻接表表示有向图
        graph = {}
        # 构建图顶点
        for word in words:
            for w in word:
                if w not in graph:
                    graph[w] = []
        # 两两单词进行比较,确定图的方向
        for i in range(len(words) - 1):
            j = 0
            while j < len(words[i]) and j < len(words[i + 1]):
                if words[i][j] != words[i + 1][j]:
                    graph[words[i][j]].append(words[i + 1][j])
                    break
                j += 1
        # 拓扑排序输出字母顺序
        in_degrees = {}
        topo_result = []
        for k in graph:
            in_degrees[k] = 0  # 初始化顶点入度为0
        for values in graph.values():
            for value in values:
                in_degrees[value] += 1  # 计算每个顶点的入度
        zeros = [k for (k, v) in in_degrees.items() if v == 0]
        dequeues = []  # 出队元素
        while zeros != []:
            node = zeros.pop()
            dequeues.append(node)
            topo_result.append(node)
            for value in graph[node]:
                in_degrees[value] -= 1  # 删除该入度为0的节点后,该节点指向的节点入度减1
                if in_degrees[value] == 0:
                    zeros.append(value)
        # 判断非法顺序(判断有向图是否有环)
        is_unval = False
        if len(dequeues) != len(graph):  # 出队元素个数不等于图顶点个数,说明有环
            is_unval = True
        
        # abc 排在 ab前面,也属于非法输入。。。。
        for i in range(len(words) - 1):
            if len(words[i]) > len(words[i + 1]) and words[i][:len(words[i + 1])] == words[i + 1]:
                is_unval = True
                break

        if is_unval:
            return ""
        # 无法判断顺序的返回随机顺序
        if not is_unval and topo_result == []:
        
            return "".join([k for k in graph])
        return "".join(topo_result)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值