Go&Java算法之和为S的连续正数序列

208 阅读1分钟

这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

和为S的连续正数序列

输入一个正整数 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

题解

方法一:滑动窗口——Java

设连续正整数序列的左边界 i 和右边界 j ,则可构建滑动窗口从左向右滑动。循环中,每轮判断滑动窗口内元素和与目标值 target 的大小关系,若相等则记录结果,若大于 target 则移动左边界 i (以减小窗口内的元素和),若小于 target 则移动右边界 j (以增大窗口内的元素和)。

class Solution {

    public int[][] findContinuousSequence(int target) {
        List<int[]> res = new ArrayList<>();
        int left = 1;
        int right = 2;
        int sum = 3;
        while (left < right) {
            if (sum == target) {
                int[] arr = new int[right - left + 1];
                for (int i = left; i <= right; i++) {
                    arr[i - left] = i;
                }
                res.add(arr);
                sum -= left;
                left++;
            } else if (sum < target) {
                right++;
                sum += right;
            } else {
                sum -= left;
                left++;
            }
        }
        return res.toArray(new int[res.size()][]);
    }
}

时间复杂度:O(N)

空间复杂度:O(1)

方法一:滑动窗口——Go

func findContinuousSequence(target int)(res [][]int) {
	i,j,sum:=1,2,3

	for i<=target/2{
		if target>sum{
			j++
			sum+=j
		}else{
            if target==sum{
           tmp:=make([]int,j-i+1)
			for k:=i;k<=j;k++{
				tmp[k-i]=k
			}
			res=append(res,tmp)
            }
			sum-=i
			i++
		}					
	}
	return
}

时间复杂度:O(N)

空间复杂度:O(1)

方法二:枚举法——Java

枚举每个正整数为起点,判断以它为起点的序列和 sum 是否等于 target 即可,由于题目要求序列长度至少大于 2,所以枚举的上界为(target / 2)向下取整

class Solution {
    public int[][] findContinuousSequence(int target) {
        List<int[]> vec = new ArrayList<int[]>();
        int sum = 0, limit = (target - 1) / 2; // (target - 1) / 2 等效于 target / 2 下取整
        for (int i = 1; i <= limit; ++i) {
            for (int j = i;; ++j) {
                sum += j;
                if (sum > target) {
                    sum = 0;
                    break;
                } else if (sum == target) {
                    int[] res = new int[j - i + 1];
                    for (int k = i; k <= j; ++k) {
                        res[k - i] = k;
                    }
                    vec.add(res);
                    sum = 0;
                    break;
                }
            }
        }
        return vec.toArray(new int[vec.size()][]);
    }
}