力扣每日一练(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;
    }
}
相关推荐
linx29517 小时前
单元九 · 零基础路线图-第 7–9 周·类与 RAII
c语言·开发语言·数据结构·c++·嵌入式硬件·算法
布莱克60517 小时前
C++ 七大排序算法详解:选择、冒泡、插入、计数、堆、快速与归并排序
数据结构·c++·算法·排序算法
ocean210317 小时前
2025-2026年AI应用开发与Agent面试高频知识点洞察
人工智能·面试·职场和发展
shehuiyuelaiyuehao17 小时前
算法44,模拟算法,数青蛙
算法·哈希算法·散列表
hanlin0318 小时前
刷题笔记:力扣第287题-寻找重复数
笔记·算法·leetcode
kevin_kang18 小时前
第02章 对话时间线与延迟分析
算法
测试199818 小时前
Jmeter接口自动化测试:Jmeter变量的使用
自动化测试·软件测试·测试工具·jmeter·职场和发展·测试用例·接口测试
科学实验家18 小时前
最小生成树:Prim,kruskal
数据结构·c++·算法
学习智者18 小时前
《玄》IDE v3.6.3重磅发布:全功能修复与性能飞跃
开发语言·c++·ide·算法·中文语言 玄
Jasmine_llq18 小时前
《P10263 [GESP202403 八级] 公倍数问题》
算法·数论·快速 io 优化·埃氏筛(倍数枚举)·线性遍历求和