入门力扣自学笔记101 C++ (题目编号:剑指Offer二 115)

编程入门 行业动态 更新时间:2024-10-28 18:22:40

入门力扣自学笔记101 C++ (题目编号:<a href=https://www.elefans.com/category/jswz/34/1769671.html style=剑指Offer二 115)"/>

入门力扣自学笔记101 C++ (题目编号:剑指Offer二 115)

剑指 Offer II 115. 重建序列

题目:

给定一个长度为 n 的整数数组 nums ,其中 nums 是范围为 [1,n] 的整数的排列。还提供了一个 2D 整数数组 sequences ,其中 sequences[i] 是 nums 的子序列。
检查 nums 是否是唯一的最短 超序列 。最短 超序列 是 长度最短 的序列,并且所有序列 sequences[i] 都是它的子序列。对于给定的数组 sequences ,可能存在多个有效的 超序列 。

例如,对于 sequences = [[1,2],[1,3]] ,有两个最短的 超序列 ,[1,2,3] 和 [1,3,2] 。
而对于 sequences = [[1,2],[1,3],[1,2,3]] ,唯一可能的最短 超序列 是 [1,2,3] 。[1,2,3,4] 是可能的超序列,但不是最短的。
如果 nums 是序列的唯一最短 超序列 ,则返回 true ,否则返回 false 。
子序列 是一个可以通过从另一个序列中删除一些元素或不删除任何元素,而不改变其余元素的顺序的序列。


示例 1:

输入:nums = [1,2,3], sequences = [[1,2],[1,3]]
输出:false
解释:有两种可能的超序列:[1,2,3]和[1,3,2]。
序列 [1,2] 是[1,2,3]和[1,3,2]的子序列。
序列 [1,3] 是[1,2,3]和[1,3,2]的子序列。
因为 nums 不是唯一最短的超序列,所以返回false。


示例 2:

输入:nums = [1,2,3], sequences = [[1,2]]
输出:false
解释:最短可能的超序列为 [1,2]。
序列 [1,2] 是它的子序列:[1,2]。
因为 nums 不是最短的超序列,所以返回false。


示例 3:

输入:nums = [1,2,3], sequences = [[1,2],[1,3],[2,3]]
输出:true
解释:最短可能的超序列为[1,2,3]。
序列 [1,2] 是它的一个子序列:[1,2,3]。
序列 [1,3] 是它的一个子序列:[1,2,3]。
序列 [2,3] 是它的一个子序列:[1,2,3]。
因为 nums 是唯一最短的超序列,所以返回true。


提示:

n == nums.length
1 <= n <= 104
nums 是 [1, n] 范围内所有整数的排列
1 <= sequences.length <= 104
1 <= sequences[i].length <= 104
1 <= sum(sequences[i].length) <= 105
1 <= sequences[i][j] <= n
sequences 的所有数组都是 唯一 的
sequences[i] 是 nums 的一个子序列


来源:力扣(LeetCode)
链接:
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


思路:

拓扑排序

按照题目的要求,若在 seqs 的某个序列中数字 i 出现在数字 j 之前,那么由 seqs 重建的序列中数字 i 一定出现在 j 之前,也就是说重建的序列 org 就是由 seqs 确定的拓扑排序。题目中要求 org 是由 seqs 重建的唯一的序列,即序列 org 为由 seqs 确定的唯一的拓扑排序。

需要使用一个哈希表记录由 seqs 构建图的各节点的邻接表,用一个数组记录各节点的入度。之后在使用队列进行广度优先搜索确定图的拓扑排序时,因为需要满足唯一性,所以每次入度为 0 的节点必须唯一,且需要与 org 中一一对应。完整代码如下,因为节点数 v 为 org.size(),边的个数 e 为 O(sum(seqs[i].size)),所以时间复杂度为 O(v + e)。


代码:

class Solution {
public:bool sequenceReconstruction(vector<int>& org, vector<vector<int>>& seqs) {// 建图unordered_map<int, unordered_set<int>> graph;vector<int> inDegree(org.size() + 1, -1);for (auto& seq : seqs) {for (int& n : seq) {// 节点需要合法if (n < 1 || n > org.size()) {return false;}if (!graph.count(n)) {graph[n] = {};}if (inDegree[n] == -1) {inDegree[n] = 0;}}for (int i = 0; i < seq.size() - 1; ++i) {int num1 = seq[i];int num2 = seq[i + 1];if (!graph[num1].count(num2)) {graph[num1].insert(num2);inDegree[num2]++;}}}// 初始化队列queue<int> que;int index = 0;for (int i = 1; i < inDegree.size(); ++i) {if (inDegree[i] == 0) {// 存在唯一入度为 0 的节点,且与 org[0] 相等if (que.size() == 0 && org[index++] == i) {que.push(i);}else {return false;}}}// BFSwhile (!que.empty()) {int node = que.front();que.pop();for (auto& n : graph[node]) {inDegree[n]--;if (inDegree[n] == 0) {// 每次只存在唯一入度为 0 的节点,且与 org[index] 相等if (que.size() == 0 && org[index++] == n) {que.push(n);}else {return false;}                    }}}return index == org.size();}
};

更多推荐

入门力扣自学笔记101 C++ (题目编号:剑指Offer二 115)

本文发布于:2024-02-12 21:19:31,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1689451.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:剑指   入门   题目   编号   笔记

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!