跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

算法题解:牛客 NC221681 dd 爱框框

本题要求寻找和大于等于给定值 x 的最短连续子数组。核心思路是利用滑动窗口技术,通过左右指针动态调整区间范围并维护当前和。当窗口和满足条件时尝试收缩左边界以寻找更优解,否则扩展右边界。该方案时间复杂度为 O(n),空间复杂度为 O(1)。以下提供 C++ 完整实现,包含输入读取、逻辑判断及结果输出。

颠三倒四发布于 2026/3/28更新于 2026/7/2143 浏览
算法题解:牛客 NC221681 dd 爱框框

问题描述

给定一个包含 n 个整数的数组和一个目标值 x,需要找到一个连续子数组,使其元素之和大于等于 x。如果有多个满足条件的子数组,通常希望找到长度最短的一个。

解题思路

这道题如果采用暴力枚举所有子数组的方法,时间复杂度会达到 O(n^2),在数据量较大时容易超时。我们可以利用滑动窗口(双指针)的策略将效率优化到 O(n)。

具体做法是维护两个指针 prev 和 cur,分别代表窗口的左边界和右边界。同时用一个变量 sum 来记录当前窗口内元素的总和。

当 sum 小于 x 时,说明当前窗口还不够大,无法覆盖目标值,此时需要扩大窗口,让 cur 向右移动并累加新加入的元素。

一旦 sum 达到或超过 x,我们就找到了一个满足条件的窗口。为了寻找更短的窗口,我们需要尝试收缩左边界,即让 prev 向右移动,并从 sum 中减去移出的元素。在这个过程中,如果发现了比之前记录的更短的有效窗口,就更新最佳位置。

重复上述过程直到 cur 遍历完整个数组。

代码实现

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 读取输入规模 n 和目标值 x
    int n, x;
    cin >> n >> x;

    vector<int> arr(n);
    for(int i = 0; i < n; i++) {
        cin >> arr[i];
    }

    // 用于存储最终结果的起始和结束索引
    // 初始化为 0,表示尚未找到有效区间
    int index[2] = {0};
    
    // 滑动窗口初始化
    int cur = 0;      // 右指针
    int prev = 0;     // 左指针
    int sum = 0;      // 当前窗口和

    while(cur < n) {
        sum += arr[cur]; // 扩展右边界
        
        // 当窗口和满足条件时,尝试收缩左边界以寻找更优解
        while(sum >= x) {
            // 如果是第一次找到有效窗口,直接记录
            if(index[0] == 0 && index[1] == 0) {
                index[0] = prev;
                index[1] = cur;
                sum -= arr[prev++];
                continue;
            }

            // 比较当前窗口长度与已记录的最短长度
            // 注意:index 存储的是下标,长度计算需考虑偏移
            int currentLen = cur - prev + 1;
            int bestLen = index[1] - index[0] + 1;

            // 如果当前更短,则更新最佳记录
            if(currentLen < bestLen) {
                index[0] = prev;
                index[1] = cur;
            }
            
            // 收缩左边界
            sum -= arr[prev++];
        }
        cur++; // 继续扩展右边界
    }

    // 输出结果(转换为 1-based 索引)
    cout << index[0] + 1 << " " << index[1] + 1 << endl;
    return 0;
}

关键点说明

  1. 双指针协作:cur 负责探索新的可能性,prev 负责在满足条件后尝试优化结果。两者都只向右移动,保证了线性时间复杂度。
  2. 状态重置:sum 随着窗口的伸缩动态变化,不需要重新计算区间和,这是滑动窗口高效的关键。
  3. 边界处理:注意数组下标从 0 开始,但题目通常要求输出 1-based 的索引,记得在最后输出时加 1。

目录

  1. 问题描述
  2. 解题思路
  3. 代码实现
  4. 关键点说明
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 纯前端开源 PDF 压缩工具:Vue3+TypeScript 实现方案
  • C++ 引用、inline 和 nullptr:从混淆到清晰
  • 从零开始学编程:五种最适合新手的入门语言
  • Elasticsearch 中指定数组字段的统计查询记录
  • C++ STL 算法实战:查找、排序与数值处理
  • Python 正则表达式入门:基础语法与 re 模块实战
  • 跨平台 Web 字体渲染方案与性能优化实践
  • Spring 事务核心:@Transactional 注解与传播机制详解
  • Trae AI 编程工具使用指南与竞品对比分析
  • 大模型应用实战:原理、场景与 Prompt 技巧
  • HarmonyOS 6 凹陷圆形底部导航组件 rc_concave_tabbar 实战指南
  • C/C++ 算法入门:一维动态规划基础实战
  • 纯 C# 自研轻量 UI 引擎:XchyUI 架构解析与性能实践
  • Copilot 与 Codeium 等 AI 代码助手核心技术解析
  • C++ 类的默认成员函数详解及日期类实现
  • 免费开源漫画阅读器 Komikku 使用指南
  • AIGC 时代的核心协议:深入理解 Model Context Protocol (MCP)
  • Spring Boot 分组校验、自定义注解与 Redis 登录验证实战
  • 基于 Rokid CXR-M SDK 的 AR 演讲提词器开发实战
  • C++ STL list 双向链表实现与迭代器详解

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online