[LeetCode] Sequence Reconstruction 序列重建
Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. The org sequence is a permutation of the integers from 1 to n, with 1 ≤ n ≤ 104. Reconstruction means building a shortest common supersequence of the sequences in seqs (i.e., a shortest sequence so that all sequences in seqs are subsequences of it). Determine whether there is only one sequence that can be reconstructed from seqs and it is the org sequence.
Example 1:
Input:
org: [1,2,3], seqs: [[1,2],[1,3]] Output:
false Explanation:
[1,2,3] is not the only one sequence that can be reconstructed, because [1,3,2] is also a valid sequence that can be reconstructed.
Example 2:
Input:
org: [1,2,3], seqs: [[1,2]] Output:
false Explanation:
The reconstructed sequence can only be [1,2].
Example 3:
Input:
org: [1,2,3], seqs: [[1,2],[1,3],[2,3]] Output:
true Explanation:
The sequences [1,2], [1,3], and [2,3] can uniquely reconstruct the original sequence [1,2,3].
Example 4:
Input:
org: [4,1,5,2,6,3], seqs: [[5,2,6,3],[4,1,5,2]] Output:
true
这道题给了我们一个序列org,又给我们了一些子序列seqs,问这些子序列能否唯一的重建出原序列。能唯一重建的意思就是任意两个数字的顺序必须是一致的,不能说在一个子序列中1在4的后面,但是在另一个子序列中1在4的前面,这样就不是唯一的了。还有一点就是,子序列seqs中不能出现其他的数字,就是说必须都是原序列中的数字。那么我们可以用了一个一维数组pos来记录org中每个数字对应的位置,然后用一个flags数字来标记当前数字和其前面一个数字是否和org中的顺序一致,用cnt来标记还需要验证顺序的数字的个数,初始化cnt为n-1,因为n个数字只需要验证n-1对顺序即可,然后我们先遍历一遍org,将每个数字的位置信息存入pos中,然后再遍历子序列中的每一个数字,还是要先判断数字是否越界,然后我们取出当前数字cur,和其前一位置上的数字pre,如果在org中,pre在cur之后,那么直接返回false。否则我们看如果cur的顺序没被验证过,而且pre是在cur的前一个,那么标记cur已验证,且cnt自减1,最后如果cnt为0了,说明所有顺序被成功验证了,参见代码如下:
解法一:
class Solution {
public:
bool sequenceReconstruction(vector<int>& org, vector<vector<int>>& seqs) {
if (seqs.empty()) return false;
int n = org.size(), cnt = n - ;
vector<int> pos(n + , ), flags(n + , );
bool existed = false;
for (int i = ; i < n; ++i) pos[org[i]] = i;
for (auto& seq : seqs) {
for (int i = ; i < seq.size(); ++i) {
existed = true;
if (seq[i] <= || seq[i] > n) return false;
if (i == ) continue;
int pre = seq[i - ], cur = seq[i];
if (pos[pre] >= pos[cur]) return false;
if (flags[cur] == && pos[pre] + == pos[cur]) {
flags[cur] = ; --cnt;
}
}
}
return cnt == && existed;
}
};
下面这种方法跟上面的方法大同小异,用两个哈希表来代替了上面的数组和变量,其中m为数字和其位置之间的映射,pre为当前数字和其前一个位置的数字在org中的位置之间的映射。跟上面的方法的不同点在于,当遍历到某一个数字的时候,我们看当前数字是否在pre中有映射,如果没有的话,我们建立该映射,注意如果是第一个位置的数字的话,其前面数字设为-1。如果该映射存在的话,我们对比前一位数字在org中的位置和当前的映射值的大小,取其中较大值。最后我们遍历一遍org,看每个数字的映射值是否是前一个数字的位置,如果有不是的返回false,全部验证成功返回true,参见代码如下:
解法二:
class Solution {
public:
bool sequenceReconstruction(vector<int>& org, vector<vector<int>>& seqs) {
unordered_map<int, int> m, pre;
for (int i = ; i < org.size(); ++i) m[org[i]] = i;
for (auto& seq : seqs) {
for (int i = ; i < seq.size(); ++i) {
if (!m.count(seq[i])) return false;
if (i > && m[seq[i - ]] >= m[seq[i]]) return false;
if (!pre.count(seq[i])) {
pre[seq[i]] = (i > ) ? m[seq[i - ]] : -;
} else {
pre[seq[i]] = max(pre[seq[i]], (i > ) ? m[seq[i - ]] : -);
}
}
}
for (int i = ; i < org.size(); ++i) {
if (pre[org[i]] != i - ) return false;
}
return true;
}
};
参考资料:
https://leetcode.com/problems/sequence-reconstruction/submissions/
https://discuss.leetcode.com/topic/65737/concise-c-solution-inspired-by-previous-great-solutions
https://discuss.leetcode.com/topic/65961/simple-solution-one-pass-using-only-array-c-92ms-java-16ms
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Sequence Reconstruction 序列重建的更多相关文章
- Leetcode: Sequence Reconstruction
Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. Th ...
- OpenJudge 由中根顺序和后根序列重建二叉树
题目内容: 我们知道如何按照三种深度优先次序来周游一棵二叉树,来得到中根序列.前根序列和后根序列.反过来,如果给定二叉树的中根序列和后根序列,或者给定中根序列和前根序列,可以重建一二叉树.本题输入一棵 ...
- python3 第十七章 - sequence(序列)
之前我们在讲for循环语句时就提到过序列,那么什么是序列(sequence)? 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 —— 它的索引(位置),第一个索引是0,第二个索引 ...
- EF中创建、使用Oracle数据库的Sequence(序列)功能
** 背景 ** 项目中订单号原来的生成规则由日期加随机数组成,后期需求决定将订单号生成规则更改为生成日期加当天当前订单数. 每天的订单数都是从0开始的,每生成一个订单,订单数就应该加1.订单数应该是 ...
- LeetCode 406. 根据身高重建队列(Queue Reconstruction by Height) 46
406. 根据身高重建队列 406. Queue Reconstruction by Height 题目描述 假设有打乱顺序的一群人站成一个队列.每个人由一个整数对 (h, k) 表示,其中 h 是这 ...
- [LeetCode]444. Sequence Reconstruction
Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. Th ...
- 【LeetCode每天一题】Permutation Sequence(排列序列)
The set [1,2,3,...,n] contains a total of n! unique permutations.By listing and labeling all of the ...
- [LeetCode] 903. Valid Permutations for DI Sequence DI序列的有效排列
We are given S, a length n string of characters from the set {'D', 'I'}. (These letters stand for &q ...
- [LeetCode] 936. Stamping The Sequence 戳印序列
You want to form a `target` string of lowercase letters. At the beginning, your sequence is target.l ...
随机推荐
- Python基础(二)
本章内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典.set集合) for 循环 enumrate range和x ...
- Unity3D移动平台动态读取外部文件全解析
前言: 一直有个想法,就是把工作中遇到的坑通过自己的深挖,总结成一套相同问题的解决方案供各位同行拍砖探讨.眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动大脑 ...
- spring整合mybatis使用<context:property-placeholder>时的坑
背景 最近项目要上线,需要开发一个数据迁移程序.程序的主要功能就是将一个数据库里的数据,查询出来经过一系列处理后导入另一个数据库.考虑到开发的方便快捷.自然想到用spring和mybatis整合一下. ...
- Elasticsearch的CRUD:REST与Java API
CRUD(Create, Retrieve, Update, Delete)是数据库系统的四种基本操作,分别表示创建.查询.更改.删除,俗称"增删改查".Elasticsearch ...
- 使用C#,轻松发邮件之QQ邮箱
参考来源 http://www.cnblogs.com/youring2/archive/2008/11/29/1343911.html
- 如何在Windows Server 2008 R2 SP1安装Redis-x64-3.2.100,并且自动注册服务
1.官网:http://redis.io/ 2.下载地址:https://github.com/MSOpenTech/redis/releases 3.最新的安装包: 4.点击msi文件开始安装. 5 ...
- 《连载 | 物联网框架ServerSuperIO教程》- 3.设备驱动介绍
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
- ArrayList LinkedList源码解析
在java中,集合这一数据结构应用广泛,应用最多的莫过于List接口下面的ArrayList和LinkedList; 我们先说List, public interface List<E> ...
- 使用JQuery统计input和textarea文字输入数量代码
本文主要介绍了jQuery实现统计输入文字个数的方法,需要的朋友可以参考下. HTML部分: <input type="text" value="我是输入的文字&q ...
- 用Kotlin语言重新编写Plaid APP:经验教训(II)
原文标题:Converting Plaid to Kotlin: Lessons learned (Part 2) 原文链接:http://antonioleiva.com/plaid-kotlin- ...