[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 ...
随机推荐
- 【基于WinForm+Access局域网共享数据库的项目总结】之篇三:Access远程连接数据库和窗体打包部署
篇一:WinForm开发总体概述与技术实现 篇二:WinForm开发扇形图统计和Excel数据导出 篇三:Access远程连接数据库和窗体打包部署 [小记]:最近基于WinForm+Access数据库 ...
- java多线程--同步屏障CyclicBarrier的使用
CyclicBarrier的概念理解: CyclicBarrier的字面上的意思是可循环的屏障,是java并发包java.util.concurrent 里的一个同步工具类,在我下载的JDK1.6的中 ...
- 读书笔记--SQL必知必会13--创建高级联结
13.1 使用表别名 SQL可以对列名.计算字段和表名起别名. 缩短SQL语句 允许在一条SELECT语句中多次使用相同的表. 注意:表别名只在查询执行中使用,不返回到客户端. MariaDB [sq ...
- 压力测试之badboy和Jmeter的简单使用方法
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 所谓压力测试是指,通过确定一个系统的瓶颈或者不能接收的性能点, ...
- Introduction of python
"Life is short, you need Python!" Python (British pronunciation:/ˈpaɪθən/ American pronunc ...
- “为什么DirectX里表示三维坐标要建一个4*4的矩阵?”
0x00 前言 首先要说明的是,本文的标题事实上来自于知乎上的一个同名问题:为什么directX里表示三维坐标要建一个4*4的矩阵? - 编程 .因此,正如Milo Yip大神所说的这个标题事实上是存 ...
- 2.JAVA之GUI编程布局
布局管理器 容器中的组件排放方式,就是布局 常见的布局管理器: **************************************************** 1.FlowLayout(流式 ...
- [vs2008]Visual Studio 2008 SP1添加或删除功能提示查找SQLSysClrTypes.msi文件
前言 今天接到领导布置的一个任务,是之前同事负责的项目.离职了,现在客户有些地方需要修改,由于我之前参与过,就落在我的头上了. 然后我就把代码弄了过来,打开发现其中需要用到水晶报表.(我觉得不好用,不 ...
- 【无私分享:ASP.NET CORE 项目实战(第二章)】添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建个数据模型,并且添加接口和实现类. 添加EF上下文对象 按照我们以前 ...
- C#开发微信门户及应用(6)--微信门户菜单的管理操作
前面几篇继续了我自己对于C#开发微信门户及应用的技术探索和相关的经验总结,继续探索微信API并分享相关的技术,一方面是为了和大家对这方面进行互动沟通,另一方面也是专心做好微信应用的底层技术开发,把基础 ...