LeetCode-算法-和为s的连续正数序列

力扣题目地址:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/

首先看题目
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。

序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

示例

示例 1:
输入:target = 9
输出:[[2,3,4],[4,5]]

示例 2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
限制:
1 <= target <= 10^5

解决思路
这道题目的解决方法其实有很多,但是我很喜欢官方题解中的双指针法(也可以叫滑动窗口法);今天就给大家讲一讲我的如何实现双指针法的吧。
既然是双指针法,那么我们肯定有两个指针,一个是左指针 left,一个是右指针 right。主要思路是这样的:我们指定 left 和 right 的一个区间,利用正整数列求和公式:sum = (left+right)*(right-left+1)*2 我们可以算出当前区间的sum值。如果 sum 等于 target 说明当前区间是我们需要的数组,再去把这个区间保存为一个数组,同时左指针右移一位(因为当前左指针和为target值的区间已被找到);如果 sum 小于 target 说明当前区间太小,需要将右指针右移一位,扩大区间;如果 sum 大于 target 说明当前区间太大,需要将左指针右移一位,减小区间。

开始我们的解题之旅:

  1. 计算当前区间sum值
  2. 如果相等,遍历区间每个值放入数组,并将左指针右移一位
  3. 如果sum小于target 右指针右移一位
  4. 如果sum大于target 左指针右移一位

代码实现:

	/**
     * https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/
     * @param target
     * @author GeYuxuan 2020-03-06 23:41:56
     * @return int[][]
     */
    public int[][] findContinuousSequence(int target) {
        List<int []> result = new ArrayList<>();
        //遍历区间
        for(int l = 1,r = 2; l < r;) {
        	//1.计算当前区间sum值
            int sum = (l+r)*(r-l+1)/2;
            //2.如果相等,遍历区间每个值放入数组,并将左指针右移一位
            if(sum == target){
                int[] a = new int[r-l+1];
                //遍历区间值,放入数组
                for(int i = l; i <= r; ++i) {
                    a[i-l] = i;
                }
                result.add(a);
                //左指针右移一位
                l++;
            }
            //3.如果sum小于target 右指针右移一位
            else if(sum < target){
                r++;
            }
            //4.如果sum大于target 左指针右移一位
            else{
                l++;
            }
        }
        return result.toArray(new int[0][]);
    }

这个活动窗口法其实也是暴力法的一种,但是他能够通过题目的特性排除一大部分的穷举区间,所以也是一种比较好的方法。

不忘初心,砥砺前行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值