柠檬微趣笔试题 - 最小两个连续子数组长度和
题目:
对于给定正整数数组A和给定正整数T,请在A中找出两个连续子数组,这两个子数组不能相交,并且两个子数组的和相等且为 T。可能会有多种方案,请返回两个子数组长度和的最小值。如果无法找到这样的方案,请返回 -1。
思路:
利用滑动窗口,记录窗口内的和 sum、窗口的左指针 left ,当窗口内的和大于给的 T 值,停下来,利用移动滑动窗口的方式,当 sum > T,将 sum - A[ left ] ,并且将左指针 left 往右移一格,当 sum < T 的时候,停止左边滑动窗口的移动,变成将滑动窗口的右指针往右移。因为,只需要子数组的长度,所以结果集 res 中,记录子数组的长度即可。
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class lingMengWeiQu3 { public static void main(String[] args) { int[] nums = {7,3,2,5}; System.out.println(minSumOfLengths(nums, 7)); } public static int minSumOfLengths (int[] A, int T){ if(A == null || A.length == 0) return -1; List<Integer> res = new ArrayList<>(); //存放子数组的长度 int sum = 0, left = 0; // 窗口内的和,窗口的左指针 for(int i = 0; i < A.length; i++){ // i 作为滑动窗口的右指针 sum += A[i]; if(sum >= T){ //窗口内的和 >= T,停下来判断是否移动窗口、还是加入结果 while(sum >= T){ if(sum > T){ sum -= A[left]; //窗口内的和,减去最左的元素 left += 1; //窗口往右移一格 }else{ //sum == T res.add(i - left + 1); //窗口长度放入结果集 left = i + 1; //窗口左指针重置 sum = 0; //窗口和清零 } } } } if(res.size() < 2) return -1; Collections.sort(res); //结果集排序 return res.get(0) + res.get(1); // 返回最小的2个 } }
注:由于是结束考试后,下来才重新写的代码,不知道 OJ 是否能通过,不过感觉应该是没问题,解题思想是用这个方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?