1764. 通过连接另一个数组的子数组得到一个数组
给你一个长度为 n
的二维整数数组 groups
,同时给你一个整数数组 nums
。
你是否可以从 nums
中选出 n
个 不相交 的子数组,使得第 i
个子数组与 groups[i]
(下标从 0 开始)完全相同,且如果 i > 0
,那么第 (i-1)
个子数组在 nums
中出现的位置在第 i
个子数组前面。(也就是说,这些子数组在 nums
中出现的顺序需要与 groups
顺序相同)
如果你可以找出这样的 n
个子数组,请你返回 true
,否则返回 false
。
如果不存在下标为 k
的元素 nums[k]
属于不止一个子数组,就称这些子数组是 不相交 的。子数组指的是原数组中连续元素组成的一个序列。
示例 1:
输入:groups = [[1,-1,-1],[3,-2,0]], nums = [1,-1,0,1,-1,-1,3,-2,0] 输出:true 解释:你可以分别在 nums 中选出第 0 个子数组 [1,-1,0,1,-1,-1,3,-2,0] 和第 1 个子数组 [1,-1,0,1,-1,-1,3,-2,0] 。 这两个子数组是不相交的,因为它们没有任何共同的元素。
示例 2:
输入:groups = [[10,-2],[1,2,3,4]], nums = [1,2,3,4,10,-2] 输出:false 解释:选择子数组 [1,2,3,4,10,-2] 和 [1,2,3,4,10,-2] 是不正确的,因为它们出现的顺序与 groups 中顺序不同。 [10,-2] 必须出现在 [1,2,3,4] 之前。
示例 3:
输入:groups = [[1,2,3],[3,4]], nums = [7,7,1,2,3,4,7,7] 输出:false 解释:选择子数组 [7,7,1,2,3,4,7,7] 和 [7,7,1,2,3,4,7,7] 是不正确的,因为它们不是不相交子数组。 它们有一个共同的元素 nums[4] (下标从 0 开始)。
提示:
groups.length == n
1 <= n <= 103
1 <= groups[i].length, sum(groups[i].length) <= 103
1 <= nums.length <= 103
-107 <= groups[i][j], nums[k] <= 107
原站题解
java 解法, 执行用时: 0 ms, 内存消耗: 41.9 MB, 提交时间: 2022-12-17 15:41:32
class Solution { public boolean canChoose(int[][] groups, int[] nums) { int p1 = 0, p2, n = nums.length; for (int[] g : groups) { p2 = 0; while (p2 < g.length && p1 < n) { if (nums[p1++] == g[p2]) p2++; else {p1 -= p2; p2 = 0;} //回到开头的下一个数字重新开始 } if (p2 != g.length) return false; } return true; } }
javascript 解法, 执行用时: 68 ms, 内存消耗: 43.6 MB, 提交时间: 2022-12-17 15:40:55
/** * @param {number[][]} groups * @param {number[]} nums * @return {boolean} */ var canChoose = function(groups, nums) { let k = 0; for (let i = 0; i < groups.length; i++) { k = find(nums, k, groups[i]); if (k == -1) { return false; } k += groups[i].length; } return true; } const find = (nums, k, g) => { let m = g.length, n = nums.length; if (k + g.length > nums.length) { return -1; } const pi = new Array(m).fill(0); for (let i = 1, j = 0; i < m; i++) { while (j > 0 && g[i] !== g[j]) { j = pi[j - 1]; } if (g[i] === g[j]) { j++; } pi[i] = j; } for (let i = k, j = 0; i < n; i++) { while (j > 0 && nums[i] !== g[j]) { j = pi[j - 1]; } if (nums[i] === g[j]) { j++; } if (j === m) { return i - m + 1; } } return -1; };
java 解法, 执行用时: 0 ms, 内存消耗: 41.7 MB, 提交时间: 2022-12-17 15:40:43
class Solution { public boolean canChoose(int[][] groups, int[] nums) { int k = 0; for (int i = 0; i < groups.length; i++) { k = find(nums, k, groups[i]); if (k == -1) { return false; } k += groups[i].length; } return true; } public int find(int[] nums, int k, int[] g) { int m = g.length, n = nums.length; if (k + g.length > nums.length) { return -1; } int[] pi = new int[m]; for (int i = 1, j = 0; i < m; i++) { while (j > 0 && g[i] != g[j]) { j = pi[j - 1]; } if (g[i] == g[j]) { j++; } pi[i] = j; } for (int i = k, j = 0; i < n; i++) { while (j > 0 && nums[i] != g[j]) { j = pi[j - 1]; } if (nums[i] == g[j]) { j++; } if (j == m) { return i - m + 1; } } return -1; } }
python3 解法, 执行用时: 40 ms, 内存消耗: 15.1 MB, 提交时间: 2022-12-17 15:40:12
class Solution: def canChoose(self, groups: List[List[int]], nums: List[int]) -> bool: k = 0 for g in groups: while k + len(g) <= len(nums): if nums[k: k + len(g)] == g: k += len(g) break k += 1 else: return False return True
golang 解法, 执行用时: 8 ms, 内存消耗: 4.8 MB, 提交时间: 2022-12-17 15:39:12
func canChoose(groups [][]int, nums []int) bool { next: for _, g := range groups { for len(nums) >= len(g) { if equal(nums[:len(g)], g) { nums = nums[len(g):] continue next } nums = nums[1:] } return false } return true } func equal(a, b []int) bool { for i, x := range a { if x != b[i] { return false } } return true }
javascript 解法, 执行用时: 72 ms, 内存消耗: 41.9 MB, 提交时间: 2022-12-17 15:38:59
/** * @param {number[][]} groups * @param {number[]} nums * @return {boolean} */ var canChoose = function(groups, nums) { let i = 0; for (let k = 0; k < nums.length && i < groups.length;) { if (check(groups[i], nums, k)) { k += groups[i].length; i++; } else { k++; } } return i === groups.length; } const check = (g, nums, k) => { if (k + g.length > nums.length) { return false; } for (let j = 0; j < g.length; j++) { if (g[j] !== nums[k + j]) { return false; } } return true; };
java 解法, 执行用时: 0 ms, 内存消耗: 41.8 MB, 提交时间: 2022-12-17 15:38:45
class Solution { public boolean canChoose(int[][] groups, int[] nums) { int i = 0; for (int k = 0; k < nums.length && i < groups.length;) { if (check(groups[i], nums, k)) { k += groups[i].length; i++; } else { k++; } } return i == groups.length; } public boolean check(int[] g, int[] nums, int k) { if (k + g.length > nums.length) { return false; } for (int j = 0; j < g.length; j++) { if (g[j] != nums[k + j]) { return false; } } return true; } }
cpp 解法, 执行用时: 8 ms, 内存消耗: 13.1 MB, 提交时间: 2022-12-17 15:38:34
class Solution { public: bool check(vector<int> &g, vector<int> &nums, int k) { if (k + g.size() > nums.size()) { return false; } for (int j = 0; j < g.size(); j++) { if (g[j] != nums[k + j]) { return false; } } return true; } bool canChoose(vector<vector<int>>& groups, vector<int>& nums) { int i = 0; for (int k = 0; k < nums.size() && i < groups.size();) { if (check(groups[i], nums, k)) { k += groups[i].size(); i++; } else { k++; } } return i == groups.size(); } };