小哆啦解题记:长度最小的子数组
小哆啦开始刷力扣的第二十五天
难题降临
在算法的神秘森林里,住着爱挑战的小哆啦。这天,他遇到了一道棘手的关卡 ——“长度最小的子数组”。题目要求是,给定一个包含 n 个正整数的数组和一个正整数 target,要找出数组里总和大于等于 target 的最短子数组的长度,要是不存在这样的子数组,就返回 0。小哆啦眼睛放光,心想:“这能难倒我?看我的!”
暴力出击
小哆啦采用了简单粗暴的暴力解题法。他打算遍历数组中所有可能的子数组,计算每个子数组的和,找出满足和大于等于 target 的最短子数组长度。于是小哆啦写下了如下代码:
function minSubArrayLen(target: number, nums: number[]): number {
let minLength = Infinity;
const n = nums.length;
// 遍历所有可能的子数组起始位置
for (let i = 0; i < n; i++) {
let sum = 0;
// 遍历以 i 为起始位置的所有子数组
for (let j = i; j < n; j++) {
sum += nums[j];
if (sum >= target) {
// 更新最小长度
minLength = Math.min(minLength, j - i + 1);
// 由于要找最短的,后续更长的子数组无需再考虑
break;
}
}
}
return minLength === Infinity ? 0 : minLength;
}
小哆啦按照这个思路,就像一个不知疲倦的小矿工,从数组的第一个元素开始,逐个检查所有可能的子数组。把每个子数组的元素加起来,看看和是否能达到或超过 target。要是满足条件,就赶紧记录下这个子数组的长度,然后接着去试下一个。小哆啦忙得晕头转向,一会儿挠挠脑袋,一会儿写写画画,嘴里还不停地嘟囔着计算结果。
小智点拨
就在小哆啦忙得不可开交的时候,聪明的小智溜达了过来。小智看着小哆啦忙乱的样子,忍不住笑着说:“小哆啦,你这样一个一个试,要是数组里的数字超级多,那不得算到猴年马月呀!” 小哆啦一听,停下手中的笔,疑惑地看着小智:“那还有啥更好的办法吗?”
小智神秘一笑,说:“试试滑动窗口的办法吧。就像有一个会滑动的小窗口在数组上移动,根据窗口内元素的和来调整窗口的大小。” 小哆啦眼睛一亮,觉得这办法听起来挺厉害,赶紧按照小智说的思路开始写代码:
function minSubArrayLen(target: number, nums: number[]): number {
let left = 0;
let sum = 0;
let minLength = nums.length + 1;
for (let right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= target) {
minLength = minLength > (right - left + 1) ? right - left + 1 : minLength;
sum -= nums[left];
left++;
}
}
return minLength === nums.length + 1 ? 0 : minLength;
}
初尝挫折
小哆啦兴奋地运行代码,结果却发现有些测试用例没有通过。他皱着眉头,像个小侦探一样仔细检查代码。小智在一旁鼓励他:“别着急,再看看哪里出了问题。滑动窗口的关键就是要合理调整左右指针的位置。”
修正凯旋
小哆啦静下心来,重新梳理思路。他发现原来是在更新 minLength 和移动指针的时候,逻辑出现了一点小偏差。经过一番修改,他终于得到了正确的代码:
function minSubArrayLen(target: number, nums: number[]): number {
let left = 0;
let sum = 0;
// 初始化为无穷大,方便后续比较更新
let minLength = Infinity;
for (let right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= target) {
minLength = Math.min(minLength, right - left + 1);
sum -= nums[left];
left++;
}
}
return minLength === Infinity ? 0 : minLength;
}
这一次,代码顺利通过了所有测试用例。小哆啦高兴得跳了起来,抱着小智说:“谢谢你,小智!滑动窗口的办法太神奇了!”
结语
经过这次与 “长度最小的子数组” 的激烈交锋,小哆啦不仅成功通关,更收获了宝贵的经验和成长。在算法这片充满奇幻与挑战的森林中,每一道难题都是一座等待攀登的高峰,每一次失败都是积累智慧的宝藏。
小哆啦深刻体会到,解题就像一场冒险,有时候勇往直前的蛮劲并不能带你穿越迷雾,而巧妙的策略和灵活的思维才是开启胜利之门的钥匙。同时,朋友的陪伴与帮助就如同夜空中的繁星,在迷茫时为你指引方向。
未来,算法森林里还会有更多未知的难题等待着小哆啦。但他不再害怕,因为他知道,只要保持好奇心和求知欲,不断学习新的方法和技巧,并且珍惜身边朋友的支持,他就能在这片奇妙的世界里越走越远,攻克一个又一个看似不可能的挑战,书写属于自己的辉煌解题传奇!