描述
判断是否序列 org 能唯一地由 seqs重构得出.
org是一个由从1到n的正整数排列而成的序列,1 ≤ n ≤ 10^4。
重构表示组合成seqs的一个最短的父序列 (意思是,一个最短的序列使得所有 seqs里的序列都是它的子序列).
判断是否有且仅有一个能从 seqs重构出来的序列,并且这个序列是org。
样例
例1:
输入:org = [1,2,3], seqs = [[1,2],[1,3]]
输出: false
解释:
[1,2,3] 并不是唯一可以被重构出的序列,还可以重构出 [1,3,2]
例2:
输入: org = [1,2,3], seqs = [[1,2]]
输出: false
解释:
能重构出的序列只有 [1,2].
例3:
输入: org = [1,2,3], seqs = [[1,2],[1,3],[2,3]]
输出: true
解释:
序列 [1,2], [1,3], 和 [2,3] 可以唯一重构出 [1,2,3].
例4:
输入:org = [4,1,5,2,6,3], seqs = [[5,2,6,3],[4,1,5,2]]
输出:true
分析
从题可得,seqs中的序列能且仅能重构出一个org,并且org不能有冗余元素。
涉及到序列的顺序结构,可以考虑从元素的入度着手。
算法
- 基于seqs,生成拓扑图graph
- 基于拓扑图,生成入度表indegrees
- 把入度为0的元素放入列表queue
- 循环直到queue为空
- 取出queue元素
- 更新入度表
- 把入度为0的元素放入列表queue
- 判断返回的列表topo_order与org是否相同
实现
class Solution:
"""
@param org: a permutation of the integers from 1 to n
@param seqs: a list of sequences
@return: true if it can be reconstructed only one or false
"""
def sequenceReconstruction(self, org, seqs):
# write your code here
graph = self.build_graph(seqs)
topo_order = self.topological_sort(graph)
return topo_order == org
def build_graph(self, seqs):
# graph保存每个node后面紧跟的neighbor,用于生成入度表
# e.g.
# seq1=[1, 2, 3], graph[1]=[2, ], graph[2]=[3, ], graph[3]=[]
# seq2=[1, 3, 4], graph[1]=[2, 3], graph[2]=[3, ], graph[3]=[4, ], graph[4]=[]
graph = {}
for seq in seqs:
for idx, node in enumerate(seq):
if node not in graph:
graph[node] = set()
if idx < len(seq) - 1: # 防止idx + 1越界
graph[node].add(seq[idx + 1])
return graph
def get_indegrees(self, graph):
# indegrees = {0: 0, 1: 0, 2: 0, ..., n: 0} n是node的种类数,即graph的长度
# 如上例子:indegrees[1]=0, [2]=1, [3]=2, [4]=1
# 入度为m,即有m个元素能直达自身
indegrees = dict(zip([node for node in graph], [0 for _ in graph]))
for node in graph:
for neighbor in graph[node]:
indegrees[neighbor] += 1
return indegrees
def topological_sort(self, graph):
indegrees = self.get_indegrees(graph)
queue = []
# 放入起始node
for node, indegree in indegrees.items():
if indegree == 0:
queue.append(node)
topo_order = []
while queue:
if len(queue) > 1:
return None # 一个前置元素能抵达不止一个元素,即org不仅有一种排序
# 直接pass
node = queue.pop(0)
for neighbor in graph[node]:
indegrees[neighbor] -= 1
if indegrees[neighbor] == 0:
queue.append(neighbor)
topo_order.append(node)
return topo_order
学习自文章:https://www.jiuzhang.com/solution/sequence-reconstruction/#tag-highlight-lang-python
我是小白,一起努力。