当前位置: 首页 > news >正文

剑指offer-41、和为S的连续正数序列

题⽬描述

⼩明很喜欢数学,有⼀天他在做数学作业时,要求计算出 9~16 的和,他⻢上就写出了正确答案是 100 。但是他并不满⾜于此,他在想究竟有多少种连续的正数序列的和为 100 (⾄少包括两个数)。没多久,他就得到另⼀组连续正数和为 100 的序列: 18,19,20,21,22 。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

返回值描述:输出所有和为 S 的连续正数序列。序列内按照从⼩⾄⼤的顺序,序列间按照开始数字从⼩到⼤的顺序

示例1:

输⼊:9
返回值:[[2,3,4],[4,5]]

思路及解答

暴力枚举

通过双重循环尝试所有可能的序列起点和终点。

针对每⼀个索引起点,都计算后续的连续⼦数组的和,并且将元素存到临时 list 中。

如果和不超过 sum ,那么就继续往后⾯遍历;

如果和等于 sum ,则说明该连续⼦数组满⾜条件,将临时 list 添加到结果集中

如果和⼤于 sum ,则说明连续⼦数组已经超过,该索引起点的不满⾜条件,直接 break 。

注意的是,起点我们只需要遍历到 sum/2 的位置即可,因为⼤于 sum/2 的索引,任何两个数的和都⼤于 sum ,不符合条件。

import java.util.ArrayList;public class Solution {public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {ArrayList<ArrayList<Integer>> result = new ArrayList<>();if (sum < 3) return result; // 至少需要两个数,最小和为1+2=3// 序列起点最多到sum/2,因为至少两个数,第二个数肯定比sum/2大for (int i = 1; i <= sum / 2; i++) {int currentSum = 0;ArrayList<Integer> sequence = new ArrayList<>();// 从i开始累加,直到和大于等于sumfor (int j = i; j < sum; j++) {currentSum += j;sequence.add(j);if (currentSum == sum) {result.add(new ArrayList<>(sequence)); // 找到有效序列break;} else if (currentSum > sum) {break; // 已经超过,无需继续}}}return result;}
}
  • 时间复杂度:O(n²)
  • 空间复杂度:O(k),k为结果序列数

数学计算

利用等差数列求和公式进行数学优化,减少计算量。

思路:设序列长度为n,起始为x,则满足:n*(2x+n-1)/2 = sum

import java.util.ArrayList;public class Solution {public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {ArrayList<ArrayList<Integer>> result = new ArrayList<>();if (sum < 3) return result;// 序列长度n从2开始尝试(至少两个数)for (int n = 2; n * (n + 1) / 2 <= sum; n++) {// 根据求和公式推导:sum = n*(2x+n-1)/2// 解得:x = (2*sum/n - n + 1)/2int numerator = 2 * sum - n * (n - 1);int denominator = 2 * n;// x必须是正整数,且分子要能整除分母if (numerator > 0 && numerator % denominator == 0) {int x = numerator / denominator;ArrayList<Integer> sequence = new ArrayList<>();for (int i = 0; i < n; i++) {sequence.add(x + i);}result.add(sequence);}}// 由于我们从长度小的开始,需要反转结果保证序列间顺序result.sort((a, b) -> a.get(0) - b.get(0));return result;}
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

滑动窗口(最优)

使用双指针技术,动态调整窗口大小

import java.util.ArrayList;public class Solution {public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {ArrayList<ArrayList<Integer>> result = new ArrayList<>();if (sum < 3) return result;int left = 1;    // 窗口左边界int right = 2;   // 窗口右边界int currentSum = left + right; // 当前窗口和// 左边界最多到sum/2,因为至少需要两个数while (left <= sum / 2) {if (currentSum == sum) {// 找到有效序列,添加到结果ArrayList<Integer> sequence = new ArrayList<>();for (int i = left; i <= right; i++) {sequence.add(i);}result.add(sequence);// 左边界右移,继续寻找currentSum -= left;left++;} else if (currentSum < sum) {// 和太小,扩大窗口(右边界右移)right++;currentSum += right;} else {// 和太大,缩小窗口(左边界右移)currentSum -= left;left++;}}return result;}
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
http://www.rkmt.cn/news/59803.html

相关文章:

  • [论文笔记•(多智能体)]LLMs Can Simulate Standardized Patients via Agent Coevolution - 指南
  • 十载深耕一对一直播交友源码开发搭建,布谷鸟科技为您筑牢创业根基
  • 2025年热门的钢板预处理线厂家最新TOP实力排行
  • 广西一对一辅导机构口碑之选:2025南宁、柳州、桂林备受好评的补习机构
  • 小明的Spring Security入门到深入实战
  • OpenHarmony后台服务开发指南:ServiceAbility与ServiceExtensionAbility全解析 - 指南
  • 2025年比较好的光伏线缆厂家实力及用户口碑排行榜
  • 2025年评价高的高弹硬质棉厂家推荐及选择指南
  • 拒绝AI=拒绝饭碗?硅谷程序员的噩梦已经开始,我们的噩梦就在路上! - 详解
  • 2025年靠谱的拉幅定型机专用印染配件及改造用户口碑最好的厂家榜
  • 高纯气体过滤有哪些推荐?国内相关企业及产品解析
  • 2025年靠谱的包装木盒厂家推荐及采购参考
  • 2025年知名的化妆品标签优质厂家推荐榜单
  • 【GitHub每日速递 20251125】超实用!免费技术面试手册助你斩获大厂offer,还有7折福利!
  • 2025年评价高的食品标签厂家最新推荐排行榜
  • 2025年口碑好的带式干燥机实力厂家TOP推荐榜
  • 2025年比较好的印刷网版厂家实力及用户口碑排行榜
  • 2025年知名的精密网版厂家最新TOP实力排行
  • 2025年比较好的水泵拉伸件厂家推荐及选购参考榜
  • 2025年评价高的糖果扭结包装机用户好评厂家排行
  • 2025 买商标找哪家商标公司靠谱?3 大维度教你选对靠谱商标公司
  • 2025 买商标去哪里好?一文说透:从资源、安全到服务怎么选不亏
  • 2025 商标购买平台靠谱 TOP5 资质合规 + 流程透明测评,选对 = 省心!
  • AcWing 103:电影 ← 离散化(数组 + sort + STL map)
  • 2025EMI磁环/贴片磁珠/电感工厂实力排行榜
  • 2025开口同步带厂家哪家好,钢丝同步带厂家哪家好测评
  • 2025老铁门门窗定制厂家权威排行
  • 法式复古门窗哪家好?2025法式复古门窗源头厂家榜单
  • 2025上海全屋定制源头工厂综合榜单
  • geekgame记录一:unity逆向