当前位置: 面试刷题>> 通用子数组个数 (经典算法题500道)


### 题目描述补充 **题目:通用子数组个数** 给定两个整数数组 `nums1` 和 `nums2`,以及一个整数 `k`。我们称 `nums1` 的一个子数组 `A` 是“通用”的,如果子数组 `A` 的和能够通过重新排列(不一定保持原有顺序)`nums2` 的某个子数组 `B` 的元素来得到,且这两个子数组的长度相等。如果 `A` 的长度至少为 `k`,则称 `A` 为一个“合格”的通用子数组。 你需要计算 `nums1` 中所有“合格”的通用子数组的个数。 **注意**: 1. 子数组是数组中的一个连续部分。 2. 两个数组的元素不一定都是正数或都是负数。 3. 数组中的元素范围在 32 位有符号整数内。 ### 示例 **输入**: - `nums1 = [1, 2, 3, 2, 1]` - `nums2 = [2, 3, 4]` - `k = 3` **输出**: - `2` **解释**: - `[1, 2, 3]` 是一个通用子数组,因为 `nums2` 中的 `[2, 3]` 子数组可以通过重新排列得到 `[1, 2, 3]` 的和(均为 6)。 - `[2, 1, 2]` 也是一个通用子数组,因为 `nums2` 中的 `[3, 2]` 子数组可以通过重新排列得到 `[2, 1, 2]` 的和(均为 5)。 ### PHP 示例代码 ```php function numSubarraysWithSumK($nums1, $nums2, $k) { $count = 0; $sums1 = array(); $sums2 = array(); // 计算 nums2 所有子数组的和及出现的次数 helper($nums2, $sums2, 0, 0); $sum = 0; $prefixSums = array(0 => 1); // 用于记录 nums1 的前缀和及出现次数 for ($i = 0; $i < count($nums1); $i++) { $sum += $nums1[$i]; for ($j = $i; $j >= max(0, $i - $k + 1); $j--) { $target = $sum - ($j == 0 ? 0 : $prefixSums[$j-1]['sum']); if (isset($sums2[$target])) { $count += $sums2[$target]; } } if (!isset($prefixSums[$sum])) { $prefixSums[$sum] = array('sum' => $sum, 'count' => 0); } $prefixSums[$sum]['count']++; } return $count; } // 辅助函数,计算 nums2 的所有子数组和及其出现次数 function helper(&$nums, &$sums, $start, $currentSum) { $sums[$currentSum] = isset($sums[$currentSum]) ? $sums[$currentSum] + 1 : 1; if ($start < count($nums)) { helper($nums, $sums, $start + 1, $currentSum + $nums[$start]); } } // 使用示例 $nums1 = [1, 2, 3, 2, 1]; $nums2 = [2, 3, 4]; $k = 3; echo numSubarraysWithSumK($nums1, $nums2, $k); // 输出 2 ``` **注意**:上述 PHP 示例代码为了简化,直接使用了递归辅助函数来计算 `nums2` 的所有子数组和,这在实际应用中可能效率不高,特别是对于大数据集。可以考虑使用更高效的算法,如前缀和加哈希表等。 对于 Python 和 JavaScript 的实现,基本思路相同,但语法和具体实现细节会有所不同。你可以在码小课网站上找到更多相关内容的分享,以学习不同编程语言的实现方法和优化技巧。
推荐面试题