携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
Leetcode : leetcode-cn.com/problems/he…
GitHub : github.com/nateshao/le…
剑指 Offer 57 - II. 和为s的连续正数序列
题目描述 :输入一个正整数
target
,输出所有和为target
的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
难度:简单
示例 1:
输入:target = 9
输出:[[2,3,4],[4,5]]
示例 2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
Go
func findContinuousSequence(target int) [][]int {
left := 1
right := 2
var res [][]int
for left < right {
sum := (left + right) * (right - left + 1) / 2
if sum == target {
var list []int
for i := left; i <= right; i++ {
list = append(list, i)
}
res = append(res, list)
left++
} else if sum < target {
right++
} else {
left++
}
}
return res
}
方法:滑动窗口(双指针)
当窗口的和小于 target 的时候,窗口的和需要增加,所以要扩大窗口,窗口的右边界向右移动
当窗口的和大于 target 的时候,窗口的和需要减少,所以要缩小窗口,窗口的左边界向右移动
当窗口的和恰好等于 target 的时候,我们需要记录此时的结果。设此时的窗口为 [i, j), 那么我们已经找到了一个 i 开头的序列,也是唯一一个 i 开头的序列,接下来需要找 i+1 开头的序列,所以窗口的左边界要向右移动
设连续正整数序列的左边界 i 和右边界 j ,则可构建滑动窗口从左向右滑动。循环中,每轮判断滑动窗口内
元愫和与目标值 target 的大小关系,若相等则记录结果,若大于 target 则移动左边界 i (以减小窗口内的元 素和),若于 target 则移动右边界 j (以增大窗口内的元素和) 。
算法流程:
-
初始化:左边界 i = 1,右边界 j = 2,元素和 s = 3,结果列表 res ;
-
循环:
- 当 i ≥ j时跳出;
- 当s > target时:向右移动左边界 i = i + 1 ,并更新元素和 s ;
- 当s < target时:向右移动右边界 j = j + 1,并便新元索和 s ;
- 当s = target时:记绿连续整数序列,饷右移动左边界 i = i + 1 ;
-
返回值:返回结果列表 res ;
复杂度分析;
- 时间复杂度:由于两个指针移动均单调不减,且最多移动| target / 2 | 次,即方法一提到的枚举的上界,所 以时间复杂度为 O(target) 。
- 空间复杂度:O(1) ,除了答案数组织需要常数的空间存放若干变量。
package com.nateshao.sword_offer.topic_44_findContinuousSequence;
import java.util.ArrayList;
import java.util.List;
/**
* @date Created by 邵桐杰 on 2022/1/25 15:37
* @微信公众号 千羽的编程时光
* @个人网站 www.nateshao.cn
* @博客 https://nateshao.gitee.io
* @GitHub https://github.com/nateshao
* @Gitee https://gitee.com/nateshao
* Description:
*/
public class Solution {
public static void main(String[] args) {
int[][] findContinuousSequence = findContinuousSequence(9);
for (int[] ints : findContinuousSequence) {
for (int anInt : ints) {
System.out.println("anInt = " + anInt);
}
}
}
/**
* 解法:滑动窗口(双指针)
* @param target
* @return
*/
public static int[][] findContinuousSequence(int target) {
int i = 1, j = 2, s = 3;
List<int[]> res = new ArrayList<>();
while (i < j) {
if (s == target) {
int[] ans = new int[j - i + 1];
for (int k = i; k <= j; k++)
ans[k - i] = k;
res.add(ans);
}
if (s >= target) {
s -= i;
i++;
} else {
j++;
s += j;
}
}
return res.toArray(new int[0][]);
}
}
参考链接:leetcode-cn.com/problems/he…
\