目录
题目解析 | 如何在数组中顺序匹配多个子数组?
题目描述
给定一个二维整数数组 groups 和一个一维整数数组 nums,判断是否能够依次在 nums 中找到 groups 中的每一个子数组,且这些子数组在 nums 中是顺序出现且互不重叠的。
换句话说,是否存在一组索引,使得 nums 中连续的子数组分别等于 groups 中的每个数组,并且这些子数组的顺序与 groups 中相同。
输入
groups:二维整数数组,每个元素是一个整数数组。nums:一维整数数组。
输出
- 返回布尔值
True或False:
-
- 如果能够顺序匹配所有
groups的子数组,则返回True。 - 否则返回
False。
- 如果能够顺序匹配所有
解题分析
这道题的核心是“顺序匹配多个子数组”,且每个匹配都不能重叠。具体要点包括:
- 顺序匹配:必须依照
groups中子数组的顺序,依次在nums中找到对应的子数组。 - 不重叠:每次匹配成功后,下一次搜索必须从上次匹配结束的位置继续,不能重用之前已经匹配过的元素。
- 连续匹配:每个子数组匹配时必须是连续的片段。
解题方法
思路
- 维护一个指针
start,表示在nums中开始匹配的起始位置。 - 对
groups中每个子数组group:
-
- 从
start位置开始,遍历nums,寻找一段长度为len(group)的连续子数组与group完全相同。 - 如果找到,更新
start为当前匹配段的末尾位置(即start += len(group)),然后继续匹配下一个group。 - 如果没有找到,说明无法完整匹配,直接返回
False。
- 从
- 如果所有
group都能匹配成功,返回True。
代码实现
from typing import List
class Solution:
def canChoose(self, groups: List[List[int]], nums: List[int]) -> bool:
start = 0 # nums中开始搜索的位置
for group in groups:
found = False
while start + len(group) <= len(nums):
if nums[start:start + len(group)] == group:
found = True
start += len(group) # 下一轮搜索从当前匹配子数组结尾开始
break
start += 1
if not found:
return False
return True
代码解析
- 变量
start:标记下一轮在nums中搜索的起始索引,防止子数组重叠。 - 双重循环结构:
-
- 外循环遍历每个
group。 - 内循环从
start到len(nums)中逐个位置尝试匹配当前group。
- 外循环遍历每个
- 匹配判断:使用切片比较
nums[start:start+len(group)]和group。 - 更新指针:一旦找到匹配,
start指针前移,避免重复使用元素。 - 返回结果:
-
- 如果所有
group都匹配成功,返回True。 - 如果有任何一个
group匹配失败,返回False。
- 如果所有
时间和空间复杂度分析
- 设:
-
m=len(groups),组数n=len(nums),数组长度k= 最大子数组长度
时间复杂度
- 最坏情况下,内层循环每次移动
start一步,最多遍历n次。 - 每次比较子数组长度为
k。 - 总体时间复杂度约为 O(m * n * k),实际中由于指针移动和提前中断,效率会比理论上的低。
空间复杂度
- 只使用了常数额外空间(指针和标志位),空间复杂度为 O(1)。
示例说明
示例1
groups = [[1, -1, -1], [3, -2, 0]]
nums = [1, -1, 0, 1, -1, -1, 3, -2, 0]
过程:
- 找
groups[0] = [1, -1, -1]在nums中连续出现的位置:
-
- 从索引0开始:
[1, -1, 0]不匹配 - 索引1:
[-1, 0, 1]不匹配 - 索引2:
[0, 1, -1]不匹配 - 索引3:
[1, -1, -1]匹配成功,更新start=6
- 从索引0开始:
- 找
groups[1] = [3, -2, 0]在nums中从索引6开始找:
-
- 索引6:
[3, -2, 0]匹配成功,完成所有匹配。
- 索引6:
返回 True
示例2
groups = [[10, -2], [1, 2, 3, 4]]
nums = [1, 2, 3, 4, 10, -2]
- 查找
[10, -2]:
-
- 从索引0开始:
[1, 2]不匹配 - 索引1:
[2, 3]不匹配 - 索引2:
[3, 4]不匹配 - 索引3:
[4, 10]不匹配 - 索引4:
[10, -2]匹配成功,start = 6
- 从索引0开始:
- 查找
[1, 2, 3, 4]:
-
start=6已经超过nums长度,无法匹配,返回False
总结
这道题的关键在于:
- 维护搜索起点,保证子数组不重叠。
- 顺序匹配,不能乱序查找。
- 使用切片直接比较数组是否相等,简洁有效。
实现思路简单直观,时间复杂度在中等范围,适合这类匹配问题。

被折叠的 条评论
为什么被折叠?



