【2026OD新机考】【固定滑窗】20260830-小花获胜的奶茶【Py/Java/C++/C/JS/Go六种语言OD真题】【欧弟算法】全网注释最详细分类最全的华子OD真题题解

文章目录

  • 相关推荐阅读
  • 题目描述与示例
    • 题目描述
    • 输入描述
    • 输出描述
    • 示例
      • 输入
      • 输出
      • 说明
  • 解题思路
  • 代码
    • Python
    • Java
    • C++
    • C
    • Node JavaScript
    • Go
    • 时空复杂度
  • 华为OD算法/大厂面试高频题算法练习冲刺训练

相关推荐阅读

  • 【2026华为OD机考】最新套题持续更新【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
  • 【2026年华为OD机考最新政策】2026年新规改革最新变化 | 学习策略 | 考试时间 | 出题形式 | 输入形式 | 考前流程 | 双机位摆放
  • 【华为OD机考正在更新】2025年双机位A卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
  • 【华为OD机考】2025C+2025B+2024E+D卷真题【完全原创题解 | 详细考点分类 | 不断更新题目】
  • 【华为OD笔试】双机位A+2025C+2025B+2024E+D卷真题机考套题汇总【真实反馈,不断更新,限时免费】
  • 【华为OD笔试】2024E+D卷命题规律解读【分析500+场OD笔试考点总结】
  • 【华为OD流程】性格测试选项+注意事项

题目练习网址:【固定滑窗】20260830-小花获胜的奶茶

题目描述与示例

题目描述

小菊和小花是好朋友,他们经常一起玩游戏。这天他们玩一个数字游戏,获胜可以获得对方1杯奶茶。

游戏规则:

小菊在纸上写了一排数组,小花需要从中选择连续k个数字,使得这k个数字的和最大。

小花正确找到最大的值就是获胜,小菊则提供1杯奶茶;小花想获胜喝奶茶,请你帮助她。

输入描述

参数1:int数组,给出的一排数字

参数2:int整数,k

约束:

-2147483648 <= 单个数字 <= 2147483647 0 < 一排数字长度 < 1063 1 <= k <= 一排数字的长度

输出描述

最大k个数字和

示例

输入

1,3,8,6,4,103

输出

20

说明

6`,`4`,`10`三个数和最大,`6` + `4` + `10` = `20

解题思路

这是一个非常典型的固定滑窗问题。

容易想到,如果我们采用暴力思路,枚举所有长度为k的连续子数组并逐个求和,那么时间复杂度会达到O(n × k);注意到题目中数组长度最大接近10^3,虽然不算极大,但题目显然希望我们掌握更优的通用解法。

换句话说,我们应该利用相邻窗口之间的重叠部分来优化计算:

  • 当窗口从[i, i+k-1]向右滑动到[i+1, i+k]时,这两个窗口里的元素几乎完全一样;
  • 变化的仅仅是左侧的nums[i]离开了窗口,右侧的nums[i+k]进入了窗口。

因此,新的窗口和可以由旧窗口和的基础上在O(1)时间内推导出来,而不需要重新遍历k个元素。

直接考虑滑窗三问三答即可解决该问题,属于非常典型的模板题。

代码

Python

fromtypingimportList# 题目:【固定滑窗】20260830-小花获胜的奶茶# 分值:100# 作者:闭着眼睛学数理化# 算法:固定滑窗# 代码看不懂的地方,请直接在群上提问# 代码中的类名、方法名、参数名已经指定# @param nums: 给出的一排数字# @param k: 需要选择的连续数字个数# @return: 连续 k 个数字的最大和classSolution:defsolve(self,nums:List[int],k:int)->int:n=len(nums)# 初始化第一个窗口的累加和,即下标 [0, k-1] 这 k 个数字的总和cur_sum=0foriinrange(k):cur_sum+=nums[i]# 初始状态下,最大和就是第一个窗口的和max_sum=cur_sumforrightinrange(k,n):# A1:将 nums[right] 加入当前窗口总和,完成窗口右侧的扩张cur_sum+=nums[right]# A2:在固定滑窗中,左侧边界 left 始终等于 right - k# 换句话说,最左边的那个元素已经滑出了窗口,需要从总和中减掉left=right-k cur_sum-=nums[left]# A3:窗口移动完成后,用当前窗口和去更新历史最大和# 注意到,题目只要求返回最大和,不要求返回起始索引,因此直接取 max 即可ifcur_sum>max_sum:max_sum=cur_sumreturnmax_sum# 以下内容为 LeetCode 核心代码模式转为 ACM 模式所需代码# 请在 algomooc oj 上直接使用,在实际考试中无需编写if__name__=="__main__":nums=list(map(int,input().strip().split(',')))k=int(input().strip())print(Solution().solve(nums,k))

Java

importjava.util.Scanner;// 题目:【固定滑窗】20260830-小花获胜的奶茶// 分值:100// 作者:闭着眼睛学数理化// 算法:固定滑窗// 代码看不懂的地方,请直接在群上提问// 代码中的类名、方法名、参数名已经指定// @param nums: 给出的一排数字// @param k: 需要选择的连续数字个数// @return: 连续 k 个数字的最大和classSolution{publiclongsolve(int[]nums,intk){intn=nums.length;// 初始化第一个窗口的累加和,即下标 [0, k-1] 这 k 个数字的总和longcur_sum=0;for(inti=0;i<k;i++){cur_sum+=nums[i];}// 初始状态下,最大和就是第一个窗口的和longmax_sum=cur_sum;for(intright=k;right<n;right++){// A1:将 nums[right] 加入当前窗口总和,完成窗口右侧的扩张cur_sum+=nums[right];// A2:在固定滑窗中,左侧边界 left 始终等于 right - k// 换句话说,最左边的那个元素已经滑出了窗口,需要从总和中减掉intleft=right-k;cur_sum-=nums[left];// A3:窗口移动完成后,用当前窗口和去更新历史最大和// 注意到,题目只要求返回最大和,不要求返回起始索引,因此直接取 max 即可if(cur_sum>max_sum){max_sum=cur_sum;}}returnmax_sum;}}// 以下内容为LeetCode核心代码模式转为ACM模式所需代码// 请在algomooc oj上直接使用,在实际考试中无需编写publicclassMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);Stringline=sc.nextLine();String[]parts=line.split(",");int[]nums=newint[parts.length];for(inti=0;i<parts.length;i++){nums[i]=Integer.parseInt(parts[i].trim());}intk=Integer.parseInt(sc.nextLine().trim());System.out.println(newSolution().solve(nums,k));}}

C++

#include#include#include#includeusingnamespacestd;// 题目:【固定滑窗】20260830-小花获胜的奶茶// 分值:100// 作者:闭着眼睛学数理化// 算法:固定滑窗// 代码看不懂的地方,请直接在群上提问// 代码中的类名、方法名、参数名已经指定// @param nums: 给出的一排数字// @param k: 需要选择的连续数字个数// @return: 连续 k 个数字的最大和classSolution{public:longlongsolve(vector<int>nums,intk){intn=nums.size();// 初始化第一个窗口的累加和,即下标 [0, k-1] 这 k 个数字的总和longlongcur_sum=0;for(inti=0;i<k;i++){cur_sum+=nums[i];}// 初始状态下,最大和就是第一个窗口的和longlongmax_sum=cur_sum;for(intright=k;right<n;right++){// A1:将 nums[right] 加入当前窗口总和,完成窗口右侧的扩张cur_sum+=nums[right];// A2:在固定滑窗中,左侧边界 left 始终等于 right - k// 换句话说,最左边的那个元素已经滑出了窗口,需要从总和中减掉intleft=right-k;cur_sum-=nums[left];// A3:窗口移动完成后,用当前窗口和去更新历史最大和// 注意到,题目只要求返回最大和,不要求返回起始索引,因此直接取 max 即可if(cur_sum>max_sum){max_sum=cur_sum;}}returnmax_sum;}};// 以下内容为LeetCode核心代码模式转为ACM模式所需代码// 请在algomooc oj上直接使用,在实际考试中无需编写intmain(){string line;getline(cin,line);vector<int>nums;string token;stringstreamss(line);while(getline(ss,token,',')){nums.push_back(stoi(token));}intk;cin>>k;Solution solution;cout<<solution.solve(nums,k)<<endl;return0;}

C

#include#include#include// 题目:【固定滑窗】20260830-小花获胜的奶茶// 分值:100// 作者:闭着眼睛学数理化// 算法:固定滑窗// 代码看不懂的地方,请直接在群上提问// 代码中的类名、方法名、参数名已经指定// @param nums: 给出的一排数字// @param k: 需要选择的连续数字个数// @return: 连续 k 个数字的最大和structSolution{};voidtrim_newline(char*str){size_tlen=strlen(str);while(len>0&&(str[len-1]=='\n'||str[len-1]=='\r')){str[len-1]='\0';len--;}}longlongsolve(structSolution*solution,int*nums,intnumsSize,intk){intn=numsSize;// 初始化第一个窗口的累加和,即下标 [0, k-1] 这 k 个数字的总和longlongcur_sum=0;for(inti=0;i<k;i++){cur_sum+=nums[i];}// 初始状态下,最大和就是第一个窗口的和longlongmax_sum=cur_sum;for(intright=k;right<n;right++){// A1:将 nums[right] 加入当前窗口总和,完成窗口右侧的扩张cur_sum+=nums[right];// A2:在固定滑窗中,左侧边界 left 始终等于 right - k// 换句话说,最左边的那个元素已经滑出了窗口,需要从总和中减掉intleft=right-k;cur_sum-=nums[left];// A3:窗口移动完成后,用当前窗口和去更新历史最大和// 注意到,题目只要求返回最大和,不要求返回起始索引,因此直接取 max 即可if(cur_sum>max_sum){max_sum=cur_sum;}}returnmax_sum;}// 以下内容为LeetCode核心代码模式转为ACM模式所需代码// 请在algomooc oj上直接使用,在实际考试中无需编写intmain(){charline[1024]={0};if(fgets(line,sizeof(line),stdin)==NULL){return0;}trim_newline(line);intcapacity=16;int*nums=(int*)malloc(capacity*sizeof(int));intnumsSize=0;char*token=strtok(line,",");while(token!=NULL){intval=atoi(token);if(numsSize>=capacity){capacity*=2;nums=(int*)realloc(nums,capacity*sizeof(int));}nums[numsSize++]=val;token=strtok(NULL,",");}chark_line[64]={0};intk=0;if(fgets(k_line,sizeof(k_line),stdin)!=NULL){trim_newline(k_line);sscanf(k_line,"%d",&k);}structSolutionsolution;longlongresult=solve(&solution,nums,numsSize,k);printf("%lld\n",result);free(nums);return0;}

Node JavaScript

// 题目:【固定滑窗】20260830-小花获胜的奶茶// 分值:100// 作者:闭着眼睛学数理化// 算法:固定滑窗// 代码看不懂的地方,请直接在群上提问// 代码中的类名、方法名、参数名已经指定// @param nums: 给出的一排数字// @param k: 需要选择的连续数字个数// @return: 连续 k 个数字的最大和classSolution{solve(nums,k){constn=nums.length;// 初始化第一个窗口的累加和,即下标 [0, k-1] 这 k 个数字的总和letcur_sum=0;for(leti=0;i<k;i++){cur_sum+=nums[i];}// 初始状态下,最大和就是第一个窗口的和letmax_sum=cur_sum;for(letright=k;right<n;right++){// A1:将 nums[right] 加入当前窗口总和,完成窗口右侧的扩张cur_sum+=nums[right];// A2:在固定滑窗中,左侧边界 left 始终等于 right - k// 换句话说,最左边的那个元素已经滑出了窗口,需要从总和中减掉letleft=right-k;cur_sum-=nums[left];// A3:窗口移动完成后,用当前窗口和去更新历史最大和// 注意到,题目只要求返回最大和,不要求返回起始索引,因此直接取 max 即可if(cur_sum>max_sum){max_sum=cur_sum;}}returnmax_sum;}}// 以下内容为LeetCode核心代码模式转为ACM模式所需代码// 请在algomooc oj上直接使用,在实际考试中无需编写constreadline=require('readline');constrl=readline.createInterface({input:process.stdin,output:process.stdout});constlines=[];rl.on('line',(line)=>{lines.push(line);if(lines.length===2){rl.close();}});rl.on('close',()=>{constnums=lines[0].split(',').map(s=>parseInt(s.trim()));constk=parseInt(lines[1].trim());console.log(newSolution().solve(nums,k));});

Go

packagemainimport("bufio""fmt""os""strconv""strings")// 题目:【固定滑窗】20260830-小花获胜的奶茶// 分值:100// 作者:闭着眼睛学数理化// 算法:固定滑窗// 代码看不懂的地方,请直接在群上提问// 代码中的类名、方法名、参数名已经指定// @param nums: 给出的一排数字// @param k: 需要选择的连续数字个数// @return: 连续 k 个数字的最大和typeSolutionstruct{}func(s*Solution)solve(nums[]int,kint)int{n:=len(nums)// 初始化第一个窗口的累加和,即下标 [0, k-1] 这 k 个数字的总和cur_sum:=0fori:=0;i<k;i++{cur_sum+=nums[i]}// 初始状态下,最大和就是第一个窗口的和max_sum:=cur_sumforright:=k;right<n;right++{// A1:将 nums[right] 加入当前窗口总和,完成窗口右侧的扩张cur_sum+=nums[right]// A2:在固定滑窗中,左侧边界 left 始终等于 right - k// 换句话说,最左边的那个元素已经滑出了窗口,需要从总和中减掉left:=right-k cur_sum-=nums[left]// A3:窗口移动完成后,用当前窗口和去更新历史最大和// 注意到,题目只要求返回最大和,不要求返回起始索引,因此直接取 max 即可ifcur_sum>max_sum{max_sum=cur_sum}}returnmax_sum}// 以下内容为LeetCode核心代码模式转为ACM模式所需代码// 请在algomooc oj上直接使用,在实际考试中无需编写funcmain(){reader:=bufio.NewReader(os.Stdin)line,_:=reader.ReadString('\n')line=strings.TrimSpace(line)parts:=strings.Split(line,",")nums:=make([]int,len(parts))fori:=0;i<len(parts);i++{num,_:=strconv.Atoi(strings.TrimSpace(parts[i]))nums[i]=num}kLine,_:=reader.ReadString('\n')kLine=strings.TrimSpace(kLine)k,_:=strconv.Atoi(kLine)sol:=&Solution{}fmt.Println(sol.solve(nums,k))}

时空复杂度

  • 时间复杂度:O(n),其中n为数组长度。初始化第一个窗口需要O(k),后续滑动需要O(n-k),两者相加整体为O(n);
  • 空间复杂度:O(1),仅使用了cur_sum、max_sum、left、right等常数个额外变量,没有借助任何与数据规模相关的辅助空间。

华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华子OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务1000+同学成功上岸!

  • 课程讲师为全网200w+粉丝编程博主@吴师兄学算法以及小红书头部编程博主@闭着眼睛学数理化

  • 90+天陪伴式学习,100+直播课时,300+动画图解视频,500+LeetCode经典题,500+华为OD真题/大厂真题,还有简历修改、模拟面试、陪伴小群、资深HR对接将为你解锁