网站广告制作,优化网站速度的要点,禅城网站建设公司价格,优秀的移动端网站链接长度最小的子数组题序号209题型数组解题方法滑动窗口难度中等
题目 给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, …, numsr-1, numsr] #xff0c;并返回其长度。如果不存在符合条件…链接长度最小的子数组题序号209题型数组解题方法滑动窗口难度中等
题目 给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, …, numsr-1, numsr] 并返回其长度。如果不存在符合条件的子数组返回 0 。 示例 1 输入target 7, nums [2,3,1,2,4,3] 输出2 解释子数组 [4,3] 是该条件下的长度最小的子数组。 示例 2 输入target 4, nums [1,4,4] 输出1 示例 3 输入target 11, nums [1,1,1,1,1,1,1,1] 输出0 提示 1 target 109 1 nums.length 105 1 nums[i] 104 进阶 如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。 题解
滑动窗口法 子数组是数组中连续的、非空元素序列。 核心要点 滑动窗口使用滑动窗口双指针的方法来解决这个问题。定义两个指针 left 和 right分别表示子数组的开始和结束位置。窗口和维护一个变量 sum表示当前窗口内元素的和。窗口移动当 sum s 时移动 right 指针向右扩展窗口并将 nums[right] 加入 sum。当 sum ≥ s 时记录当前窗口的长度并尝试移动 left 指针向右缩小窗口同时从 sum 中减去 nums[left]。最小长度在每次满足 sum ≥ s 时更新最小长度的记录。 时间复杂度O(n)因为每个元素最多被访问两次一次被 right 指针访问一次被 left 指针访问。 空间复杂度O(1)因为只使用了常数级别的额外空间 c 实现算法
class Solution {
public:int minSubArrayLen(int target, vectorint nums) {int n nums.size();int left 0; // 滑动窗口左边界int sum 0; // 当前窗口的总和int minLength INT_MAX; // 最小子数组长度初始化为无穷大for (int right 0; right n; right) {sum nums[right]; // 将当前元素加入窗口// 当窗口内的和满足 target 时尝试缩小窗口while (sum target) {minLength min(minLength, right - left 1); // 更新最小长度sum - nums[left]; // 从窗口中移除左边界的值left; // 左边界右移}}// 如果没有找到符合条件的子数组返回 0return minLength INT_MAX ? 0 : minLength;}
};演示以示例1为例 c完整demo
#include iostream
#include vector
#include climits // for INT_MAX
using namespace std;class Solution {
public:int minSubArrayLen(int target, vectorint nums) {int n nums.size();int left 0; // 滑动窗口左边界int sum 0; // 当前窗口的总和int minLength INT_MAX; // 最小子数组长度初始化为无穷大for (int right 0; right n; right) {sum nums[right]; // 将当前元素加入窗口// 当窗口内的和满足 target 时尝试缩小窗口while (sum target) {minLength min(minLength, right - left 1); // 更新最小长度sum - nums[left]; // 从窗口中移除左边界的值left; // 左边界右移}}// 如果没有找到符合条件的子数组返回 0return minLength INT_MAX ? 0 : minLength;}
};int main() {Solution solution;vectorint nums {2, 3, 1, 2, 4, 3};int target 7;int result solution.minSubArrayLen(target, nums);cout result: result endl; // 输出 2return 0;
}
滑动窗口法和双指针法
滑动窗口和双指针是解决数组和字符串问题中常用的两种技术它们在某些情况下可以相互转换但它们的概念和应用场景有所不同。下面我将分别解释这两种技术并说明它们的主要区别。
滑动窗口
滑动窗口是一种处理 固定长度或动态长度窗口内元素的技术常用于解决需要在连续子数组或子字符串中寻找特定属性的问题。 滑动窗口的核心思想是维护一个窗口随着遍历的进行窗口内包含的元素会不断变化。
特点
窗口可以是固定长度也可以是动态变化的。窗口内的操作通常是累加、累乘或者比较。滑动窗口可以用于寻找子数组或子字符串的最大/最小值、和、乘积等。
应用场景
寻找子数组的和或乘积满足特定条件的最小/最大长度。判断子数组是否包含特定数量的不同元素。实现一些需要连续性条件的数据流统计。
双指针
双指针技术通常涉及两个指针或索引它们在数组或字符串中以不同的速度移动用于解决需要比较元素之间相对位置的问题。
特点
两个指针可以同时移动也可以一个快一个慢。双指针常用于比较、排序、去重、寻找特定模式等问题。双指针可以用于解决有序数组中的特定问题如寻找两个数的和、差等。
应用场景
寻找两个指针之间的特定关系如两数之和为特定值。判断一个数组是否为回文快慢指针相向而行。实现归并排序、快速排序中的合并和分区步骤。
区别
窗口大小滑动窗口通常有一个明确的窗口大小而双指针不一定有固定的大小概念。移动方式滑动窗口通常是单向移动如向右扩展而双指针可以相向而行或同向而行。问题类型滑动窗口更适合解决需要连续性的问题而双指针更适合解决需要比较元素相对位置的问题。灵活性双指针在某些情况下比滑动窗口更灵活因为它们可以独立控制每个指针的移动。
在实际应用中滑动窗口和双指针可以根据问题的具体需求相互转换。例如滑动窗口问题可以通过设置两个指针来模拟而某些双指针问题也可以通过扩展窗口来解决。理解这两种技术的核心思想和适用场景可以帮助你更有效地解决算法问题。