剑指offer 之 和为S的连续正数序列

题意

给出整型sum,问能求出多少连续序列之和等于sum,例如9 -> 45 , 234

解法

第一种:双指针,当双指针之间的和 tot == sum,low++,high++; 当 tot < sum,high++; 当tot > sum,low++;

 ArrayList<ArrayList<Integer>>  res = new ArrayList<ArrayList<Integer> > ();
   public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        if(sum<3)return res;
        int low = 1, high = 2;
        while (low < high) {
            int n = high - low + 1;
            int tot = (low+high)*n/2;
            if (tot == sum) {
                ArrayList<Integer> list = new ArrayList<>();
                System.out.println(sum + ": ");
                for(int p=low;p<=high;p++){
                    list.add(p);
                    System.out.println(p);
                }
                res.add(list);
                low++;
                high++;
            }else if(tot < sum){
                high++;
            }else{
                low++;
            }
        }
        return res;
    }

第二种:令n为连续序列的长度,那么通过n可以定位到连续序列
1)n为奇数:满足这种情况必须 sum%n==0 (中点是其因数) , n %2 == 1, 从中点向两边发散。 例如 9 -> 2 3 4
2)n为偶数: double(sum/n) - (int) sum/n == 0.5。例如 14 -> 2 3 4 5,那么3 4 必须是一个少0.5 一个多0.5。

如何定位n的范围呢? 等差数列前n项和 (n + n +1) * n /2 == S , s < sqrt( 2 * S);
如何定位序列细节呢?这种 奇或偶 / 2 , 通常可以通过 - 1去统一计算,要记住这个思想

ArrayList<ArrayList<Integer>>  res = new ArrayList<ArrayList<Integer> > ();
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        if(sum<3)return res;

        for (int i = (int) Math.sqrt(sum * 2); i >= 2; i--) {
//            System.out.println(sum + ":");
            double p1 = sum*1.0 / i;
            int p2 = sum/i;
//            System.out.println(p1 + "  " + p2 + " " + (p1-p2) );
            if ( ((p1-p2) == 0.5) || (i%2==1 && sum%i==0) ) {
                ArrayList<Integer> list = new ArrayList<>();
                for (int j = sum / i - (i - 1) / 2, p = 0; p < i; p++, j++) {
                    
                    list.add(j);
                }
                res.add(list);
            }
        }
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值