力扣每日一练(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;
    }
}
相关推荐
octopus_c1 小时前
数据结构:堆(Heap)详解
c语言·数据结构·算法
YH55269847 小时前
GPT‑5.6 Sol 原本支持 1M 上下文,Codex 现已放开此前限制,如何看待这次调整?
java·jvm·人工智能·gpt·算法·chatgpt
遥感知识服务9 小时前
从局部阈值、双极化到暗地表剔除:NASA OPERA DSWx-S1全球动态水体算法拆解
大数据·人工智能·深度学习·神经网络·算法·机器学习
晚风醉蝶9 小时前
1-13-TimSort
算法
ZJU_统一阿萨姆9 小时前
【算子开发】算子融合与Softmax_LayerNorm实现
人工智能·算法·语言模型·硬件架构
叩码以求索11 小时前
浅谈:前序遍历反转法求解N叉树的后序遍历
算法
官乐12 小时前
AI面试指南(多agent开发流程)
人工智能·面试·职场和发展
北风toto12 小时前
中缀、前缀、后缀表达式
算法·软件设计师
程序员三藏12 小时前
自动化测试用例编写详解
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例
听取WA声一片(无恶意)12 小时前
CSP-J/CSP-S 深度优先搜索(DFS)完全讲义
c++·算法·深度优先