PHP 子数组最小长度问题算法

2次阅读

滑动窗口法可求正整数数组中和≥target的最短连续子数组长度,时间复杂度O(n);若含负数则需前缀和+单调队列等替代方案。

PHP 子数组最小长度问题算法

要找到 php 数组中满足特定条件的最短子数组长度,核心在于明确“条件”是什么。常见场景是:给定一个正整数数组和目标值 target,找出和 ≥ target 的连续子数组的最小长度;若不存在则返回 0。这不是简单的排序或内置函数能解决的问题,需用滑动窗口(双指针算法,时间复杂度 O(n),空间复杂度 O(1)。

滑动窗口解法(推荐)

适用于“连续子数组”且元素为非负数的情形(如全为正整数)。维护左右两个指针,动态调整窗口范围:

  • 右指针不断右移,累加元素到当前和 sum
  • 一旦 sum ≥ target,尝试收缩左边界:在保持 sum ≥ target 前提下,移动左指针并更新最小长度
  • 每轮收缩后记录 minLength = min(minLength, right – left + 1)
  • 遍历结束仍未找到符合条件的子数组,则返回 0

PHP 实现示例

以下是一个可直接运行的函数:

function minSubArrayLen($target, $nums) {     $n = count($nums);     $left = $minLen = 0;     $sum = 0; <pre class='brush:php;toolbar:false;'>for ($right = 0; $right < $n; $right++) {     $sum += $nums[$right];     while ($sum >= $target) {         $minLen = $minLen === 0 ? $right - $left + 1 : min($minLen, $right - $left + 1);         $sum -= $nums[$left++];     } }  return $minLen;

} // 示例调用: // minSubArrayLen(7, [2,3,1,2,4,3]); // 返回 2(子数组 [4,3])

边界与注意事项

实际使用中需注意几个关键点:

立即学习PHP免费学习笔记(深入)”;

  • 数组为空或全元素小于 target 时,循环不会触发 while,$minLen 保持 0,直接返回即可
  • PHP 中整数索引数组性能最优;若输入是关联数组,建议先 array_values() 转为索引数组
  • 若数组含负数,滑动窗口失效(因为收缩左边界不一定减小 sum),此时需改用前缀和 + 单调队列 或二分查找,复杂度升至 O(n log n)
  • 避免在 while 内重复计算长度,应先更新 $minLen 再执行 $sum -= … 和 $left++

其他变体简要说明

若问题条件变化,解法也需调整:

  • 子数组乘积 ≥ target:仅适用于正数,逻辑类似,但要注意整数溢出,建议用对数转换或高精度处理
  • 子数组异或结果等于 target:无法用滑动窗口,需哈希表记录前缀异或值及其最远下标,O(n) 解决
  • 非连续子序列最小长度:退化为贪心或 DP,例如选最少个数使和 ≥ target → 直接降序排序后累加

text=ZqhQzanResources