力扣每日一练(24-1-20)

大脑里的第一想法是排列组合,直接给出超级准确的最优解。

但不适用,hhh

只要连续的n个元素大于或者等于target就可以了

题目比自己想象的要好解决

解法是使用滑动窗口算法。这个算法的基本思想是维护一个窗口,使得窗口内的元素总和大于等于目标值,然后尝试缩小窗口以找到最小的满足条件的子数组。

Python

python 复制代码
class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        n = len(nums)
        ans = n + 1
        start = 0
        end = 0
        total = 0
        while end < n:
            total += nums[end]
            while total >= target:
                ans = min(ans, end - start + 1)
                total -= nums[start]
                start += 1
            end += 1
        return 0 if ans == n + 1 else ans

C#

cs 复制代码
public class Solution {
    public int MinSubArrayLen(int target, int[] nums) {
        int n = nums.Length;
        int ans = n + 1;
        int start = 0;
        int end = 0;
        int total = 0;
        while (end < n) {
            total += nums[end];
            while (total >= target) {
                ans = Math.Min(ans, end - start + 1);
                total -= nums[start];
                start++;
            }
            end++;
        }
        return ans == n + 1 ? 0 : ans;
    }
}

解法的时间复杂度是O(n),因为每个元素最多被访问两次。

二分查找法

在这个问题中,O(n)的滑动窗口解法已经是最优解法,因为它只需要遍历一次数组。然而,如果你想要实现一个O(n log n)的解法,你可以使用二分查找的方法。这种方法的基本思想是先计算累积和数组,然后对每个累积和,使用二分查找找到最小的索引j,使得sumj - sumi >= target。

以下是这个方法的Python实现:

Python

python 复制代码
import bisect

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        n = len(nums)
        ans = n + 1
        sums = [0] * (n + 1)
        for i in range(1, n + 1):
            sums[i] = sums[i - 1] + nums[i - 1]
        for i in range(1, n + 1):
            to_find = target + sums[i - 1]
            bound = bisect.bisect_left(sums, to_find)
            if bound != len(sums):
                ans = min(ans, bound - (i - 1))
        return 0 if ans == n + 1 else ans

C#

cs 复制代码
public class Solution {
    public int MinSubArrayLen(int target, int[] nums) {
        int n = nums.Length;
        int ans = n + 1;
        int[] sums = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            sums[i] = sums[i - 1] + nums[i - 1];
        }
        for (int i = 1; i <= n; i++) {
            int to_find = target + sums[i - 1];
            int bound = Array.BinarySearch(sums, to_find);
            if (bound < 0) {
                bound = ~bound;
            }
            if (bound <= n) {
                ans = Math.Min(ans, bound - (i - 1));
            }
        }
        return ans == n + 1 ? 0 : ans;
    }
}
相关推荐
一只小小的芙厨27 分钟前
【线性DP】
学习·算法·动态规划
奋发向前wcx1 小时前
CSP-J复赛模拟赛5 王晨旭补题 2026.10.5
算法
罗湖老棍子2 小时前
C Looooops(信息学奥赛一本通- P1640)
算法·数论·同余·裴蜀定理·扩展欧几里得
Interview Aid1124 小时前
OpenAI SWE 面试流程
面试·职场和发展
我命由我123454 小时前
Photoshop - Photoshop 使用对齐功能定位元素
学习·职场和发展·产品运营·求职招聘·职场发展·产品经理·学习方法
飘尘5 小时前
从"算子"到"AI Infra":大模型背后看不见的那群人在忙什么
人工智能·算法·面试
ychqsq5 小时前
212.涟漪
经验分享·职场和发展
ychqsq5 小时前
213.取舍
经验分享·职场和发展
夏幻灵5 小时前
每日一题:LeetCode 3:无重复字符的最长子串——滑动窗口思路详解
算法·leetcode·职场和发展
CarIise6 小时前
Java实训阶段查漏补缺复习笔记2
java·linux·算法