码迷,mamicode.com
首页 > 其他好文 > 详细

和为S的连续正数序列

时间:2019-01-04 21:34:00      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:int   turn   列表   width   list   sequence   分析   div   反思   

题目描述:找出所有和为S的连续正数序列

思路分析:(一)求出连续序列的中间值和长度

  因为是连续正数序列,所以实质上是一个公差为1的等差数列,可以利用等差数列的和来计算。

 假设长度为n

(1)先算出中间值S/n,但要分以下两种情况:

   当n为奇数时,序列的中间值正好是序列的平均值;

   当n为偶数时,序列的中间两个数的平均值是序列的平均值。

(2)并且不用n不用从2计算到S,由等差数列的和为S=n*(n+1)/2  可以得到n和S的范围,具体如下图:

                                 技术分享图片

    代码实现如下:

     

import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
       ArrayList<ArrayList<Integer>>  array = new ArrayList<> ();
        for(int n= (int)Math.sqrt(2*sum);n>=2;n--)
        {
            if((n&1)==1&&sum%n==0||(sum%n)*2==n)
            {
                ArrayList<Integer> list = new ArrayList<Integer>();
                for(int i = 0,k=(sum/n)-(n-1)/2;i<n;i++,k++)
                {
                    list.add(k);
                }
                  array.add(list);
            }
          
        }
        return array;
    }
}

    (二)利用滑动窗口设置双指针的形式来调整,并且用到了等差数列求和的第二个公式S=(a1+an)*n/2;

        分别设置两个变量plow,phigh来表示滑动窗口的两端,如果当前窗口中数的和比sum的小,则需要右边窗口左移,也就是phigh++,如果比sum大,则需要左边窗口右移,也就是plow++;

   代码如下:

import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>>  array = new ArrayList<> ();
        int plow=1,phigh=2;
        while(plow<phigh)
        {
            int cur = (plow+phigh)*(phigh-plow+1)/2;
            if(cur==sum)
            {
                ArrayList<Integer> list = new ArrayList<Integer>();
                for(int i=plow;i<=phigh;i++)
                {
                    list.add(i);
                }
                array.add(list);
                plow++;
            }else if(cur>sum)
            {
                plow++;
            }else 
            {
                phigh++;
            }
        }
        return array;
    }
}

反思:以上这个滑动窗口的方法很巧妙,可以对其进行扩展,如果不是连续的数列但也是等差数列,也可以利用这个方法,关键就是指针的移动。而且要注意的是列表里存储的还是一个列表项。

和为S的连续正数序列

标签:int   turn   列表   width   list   sequence   分析   div   反思   

原文地址:https://www.cnblogs.com/Dream-chasingGirl/p/10222266.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!