(Java 剑指 offer)和为S的连续正数序列
发布日期:2021-05-07 19:44:23 浏览次数:19 分类:精选文章

本文共 2101 字,大约阅读时间需要 7 分钟。

文章目录

一、题目

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

二、题解:暴力解法

public class Test {       public static void main(String[] args) {           FindContinuousSequence(100);    }    public static ArrayList
> FindContinuousSequence(int sum) { //记录符合条件的集合 ArrayList
> lists = new ArrayList
>(); //递归遍历 for (int i = 1; i < sum; i++) { ArrayList
list = new ArrayList
(); int num = 0; //寻找符合条件的连续数字 for (int j = i; j < sum; j++) { num = num + j; if (num <= sum) { list.add(j); } if (num>=sum){ break; } } if (num == sum) { lists.add(list); } } return lists; }}

三、题解:双指针术

双指针技术,就是相当于有一个窗口,窗口的左右两边就是两个指针,我们根据窗口内值之和来确定窗口的位置和宽度。

最后当left=right时,说明 left+right 大于了 sum,所以循环结束,再往后走均大于 sum

这里用了等差数列求和公式: S = n ∗ a 1 + n ∗ ( n − 1 ) 2 ∗ d S=n*a1 + \frac{n*(n-1)}{2}*d S=na1+2n(n1)d

public class Solution {       public ArrayList
> FindContinuousSequence(int sum) { //存放结果 ArrayList
> result = new ArrayList<>(); //两个起点,相当于动态窗口的两边,根据其窗口内的值的和来确定窗口的位置和大小 int plow = 1,phigh = 2; while(phigh > plow){ //由于是连续的,差为1的一个序列,那么求和公式是(a0+an)*n/2 int cur = (phigh + plow) * (phigh - plow + 1) / 2; //相等,那么就将窗口范围的所有数添加进结果集 if(cur == sum){ ArrayList
list = new ArrayList<>(); for(int i=plow;i<=phigh;i++){ list.add(i); } result.add(list); //条件满足,窗口往后滑动一个 plow++; phigh++; //如果当前窗口内的值之和小于sum,那么右边窗口右移一下 }else if(cur < sum){ phigh++; }else{ //如果当前窗口内的值之和大于sum,那么左边窗口右移一下 plow++; } } return result; }}

四、总结

等差数列求和公式: S = n ∗ a 1 + n ∗ ( n − 1 ) 2 ∗ d S=n*a1 + \frac{n*(n-1)}{2}*d S=na1+2n(n1)d

滑动窗口法,或者称为双指针法,控制两个指针,移动

上一篇:Oracle 子查询和分页查询
下一篇:Oracle 多表查询

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2025年04月08日 02时39分15秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章