Leetcode209-长度最小的子数组[两种方法] 关键词 滑窗 二分答案 前缀和

文章目录

  • 前言
  • 题目
  • [方法一:滑窗 O(n)](#方法一:滑窗 O(n))
  • [方法二:二分答案 O(nlogn)](#方法二:二分答案 O(nlogn))

前言

  1. 左闭右开是编程中表示一段区间的最规范的方式
  2. 二分查找的正确打开方式为
cpp 复制代码
        int lo = 0, hi = n, mi;
        while (lo < hi) {
            mi = (lo + hi) / 2;
            if (k < sum[mi])
                hi = mi;
            else
                lo = mi + 1;
        }
        return lo - 1;
  1. O(nlogn)的算法不一定比O(n)的算法慢

题目


方法一:滑窗 O(n)

滑窗处理"最长子列"问题,就是左端在迫不得已的时候才收缩;

滑窗处理"最短子列"问题,就是左端积极收缩,只要有能使窗口变小的可能,就积极尝试。

本题就是后者:滑窗右端每向右挪一个元素,尝试收缩左端。

cpp 复制代码
class Solution {
    int sum = 0; // 滑窗内的数值总和
    int min(int a, int b) { return a < b ? a : b; }

public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int pl = 0, pr = 0, ans = 200000;
        // [pl, pr)左闭右开区间
        while (pr < nums.size()) {
            sum += nums[pr];
            pr++;

            if (sum < target)
                continue;

            while (sum - nums[pl] >= target) {
                sum -= nums[pl];
                pl++;
            }
            ans = min(ans, pr - pl);
        }
        return ans == 200000 ? 0 : ans;
    }
};

方法二:二分答案 O(nlogn)

预处理好前缀和之后,对于每一个右边界,二分找到对应的左边界。

cpp 复制代码
class Solution {
    int sum[100010]; // 前缀和
    int min(int a, int b) { return a < b ? a : b; }
    int find(int n, int k) // n个元素,返回值小于等于k的最后一个元素的下标
    {
        int lo = 0, hi = n, mi; // lo hi左闭右开
        while (lo < hi) {
            mi = (lo + hi) / 2;
            if (k < sum[mi])
                hi = mi;
            else
                lo = mi + 1;
        }
        return lo - 1;
    }

public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int pl = 0, pr = 0, ans = 200000;
        sum[0] = 0;
        for (int i = 0; i < nums.size(); i++)
            sum[i + 1] = sum[i] + nums[i];

        for (int i = 1; i < nums.size() + 1; i++) {
            int pos = find(nums.size() + 1, sum[i] - target);
            if (pos < 0)
                continue;
            ans = min(ans, i - pos);
        }

        return ans == 200000 ? 0 : ans;
    }
};
相关推荐
Neil今天也要学习13 分钟前
永磁同步电机无速度算法--自适应龙贝格观测器
算法
算AI2 小时前
AI辅助编程:常用的7种Prompt模式
人工智能·算法
TY-20252 小时前
机器学习算法_决策树
算法·决策树·机器学习
子豪-中国机器人2 小时前
C++ 信息学奥赛总复习题
java·jvm·算法
全干engineer4 小时前
web3-基于贝尔曼福特算法(Bellman-Ford )与 SMT 的 Web3 DeFi 套利策略研究
算法·金融·web3·去中心化·区块链·智能合约
Splendid4 小时前
Geneformer:基于Transformer的基因表达预测深度学习模型
javascript·算法
愿所愿皆可成4 小时前
机器学习之聚类Kmeans算法
算法·机器学习·kmeans·聚类
幻奏岚音4 小时前
统计学(第8版)——假设检验学习笔记(考试用)
笔记·学习·算法
hie988945 小时前
基于matlab策略迭代和值迭代法的动态规划
算法·动态规划
Coovally AI模型快速验证5 小时前
SFTrack:面向警务无人机的自适应多目标跟踪算法——突破小尺度高速运动目标的追踪瓶颈
人工智能·神经网络·算法·yolo·计算机视觉·目标跟踪·无人机