剑指 Offer 57 - II. 和为s的连续正数序列 滑动窗口规律

 

滑动窗口求解。

规律:一个有序排列的数组,求两个数的和,可以考虑使用两个指针在两端,向中间移动。如果两个指针的和大于目标数,说明两下标之间的任意数与右下标数的和一定大于目标数,那么就淘汰右下标的数,即右指针向左移动一位。再进行比较,同理,如果两个指针的数之和小于目标数,就将左标向右移动一位,再进行比较。结束条件是left≥right。 如:1,3,5,6,7,8       target=10;

一个有序排列的数组,求很多连续数字的和。可以使用两个指针(left,right)都从左边第一个数开始向右移动。创建一个数sum记录当前左右下标之间的数之和是多少,初始sum=left。      

*如果sum<target 说明两下标之间的元素和不够大,将right标向右移动一位,sum=sum+right;

*如果sum>target,说明两下标之间的元素和太大了,先将sum=sum-left ,left标向右移动一位。

*如果等于的话就记录下标之间的元素。

如:1 2 3 4 5 6   , target=9. 当left=1,right=4时,sum已经到了10;太大了,这时应该将left移到2,。等于放弃了left=1,right=5,6的可能。是合理的,因为1-4 相加大于9了,那么1-5,1-6 相加更大于9.所以放弃1是合理的。

这两个思路可以考虑到所有情况。适用于排好序的数组的计算。

class Solution {
  public static int[][] findContinuousSequence(int target) {
        //由题意可知,滑动窗口求解
       if(target<=0){
           return new int[0][0];
       }
       List<int[]> list = new ArrayList<>();
        int last = target/2+1;
        int left=1;
        int right=1;
        int sum=1;
        while(right<=last){
            if(sum<target){
                right++;
                sum+=right;
            }else if(sum>target){
                sum-=left;
                left++;
               
            }else{
                int[] arr = new int[right-left+1];
                for(int i =left;i<=right;i++){
                    arr[i-left]=i;
                }
                list.add(arr);
                 sum-=left;
                left++;
               
            }
        }
        return list.toArray(new int[list.size()][]);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值