匹配模式数组的子数组数目 II
难度:
标签:
题目描述
You are given a 0-indexed integer array nums
of size n
, and a 0-indexed integer array pattern
of size m
consisting of integers -1
, 0
, and 1
.
A subarray nums[i..j]
of size m + 1
is said to match the pattern
if the following conditions hold for each element pattern[k]
:
nums[i + k + 1] > nums[i + k]
ifpattern[k] == 1
.nums[i + k + 1] == nums[i + k]
ifpattern[k] == 0
.nums[i + k + 1] < nums[i + k]
ifpattern[k] == -1
.
Return the count of subarrays in nums
that match the pattern
.
Example 1:
Input: nums = [1,2,3,4,5,6], pattern = [1,1] Output: 4 Explanation: The pattern [1,1] indicates that we are looking for strictly increasing subarrays of size 3. In the array nums, the subarrays [1,2,3], [2,3,4], [3,4,5], and [4,5,6] match this pattern. Hence, there are 4 subarrays in nums that match the pattern.
Example 2:
Input: nums = [1,4,4,1,3,5,5,3], pattern = [1,0,-1] Output: 2 Explanation: Here, the pattern [1,0,-1] indicates that we are looking for a sequence where the first number is smaller than the second, the second is equal to the third, and the third is greater than the fourth. In the array nums, the subarrays [1,4,4,1], and [3,5,5,3] match this pattern. Hence, there are 2 subarrays in nums that match the pattern.
Constraints:
2 <= n == nums.length <= 106
1 <= nums[i] <= 109
1 <= m == pattern.length < n
-1 <= pattern[i] <= 1
代码结果
运行时间: 199 ms, 内存: 57.5 MB
/*
* 思路:
* 1. 使用IntStream来遍历nums数组的每个可能起点。
* 2. 对于每个起点,使用Stream.allMatch来检查子数组中的每个元素是否符合pattern的要求。
* 3. 统计所有符合要求的子数组数量。
*/
import java.util.stream.IntStream;
public class Solution {
public int countPatternMatches(int[] nums, int[] pattern) {
int n = nums.length;
int m = pattern.length;
return (int) IntStream.range(0, n - m)
.filter(i -> IntStream.range(0, m)
.allMatch(j -> (pattern[j] == 1 && nums[i + j + 1] > nums[i + j]) ||
(pattern[j] == 0 && nums[i + j + 1] == nums[i + j]) ||
(pattern[j] == -1 && nums[i + j + 1] < nums[i + j])))
.count();
}
}
解释
方法:
本题解首先将`nums`数组转换为一个字符序列`s`,其中每个字符代表相邻元素之间的关系:'a' 表示递减,'b' 表示相等,'c' 表示递增。接着,根据`pattern`数组生成一个目标模式字符串`t`,其中每个字符是基于`pattern`元素映射得到(-1映射为'a', 0映射为'b', 1映射为'c')。随后,代码利用字符串匹配的KMP算法中的前缀函数来查找字符串`t`在`s`中的所有出现位置,每个匹配的位置都代表一个符合条件的子数组。最后,返回这些匹配的数量。
时间复杂度:
O(n + m)
空间复杂度:
O(n + m)
代码细节讲解
🦆
在将nums数组转换为表示元素关系的字符串s时,如果nums数组长度小于2,该如何处理?
▷🦆
为什么选择使用KMP算法进行字符串匹配,而不是使用其他字符串匹配算法如Rabin-Karp或Boyer-Moore?
▷🦆
在构建目标模式字符串t时,假设pattern数组中包含除-1, 0, 1之外的其他整数,该如何处理?
▷