题目
输入一个正整数 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof
解法一:双指针确定序列范围
解题思路
- 采用快慢指针的思路,检查它们之间所有整数和 sum 的大小与 target 的关系
- 若 sum > target,则删除一个较小的值,即慢指针 + 1
- 若 sum < target,则增加一个较大的值,即快指针 + 1
- 可能的正整数最多取到 target/2 即可,结果向上取整+1
引用自作者:ruo-xu-5
–执行用时:0 ms --内存消耗:4.7 MB
func findContinuousSequence(target int) [][]int {
//可能的正整数最多取到 target/2 即可,结果向上取整+1
max := target >> 1 + 1
nums := make([]int,max+1)
ret := make([][]int,0)
//将所有可能和为target的正整数放进一个数组
for i,_:=range nums{
nums[i]=i
}
//sum=left+right
left,right,sum:=1,2,3
for left<right && right<=max{
//sum < target,增加一个较大的值,快指针 right + 1
if sum<target{
right++
sum+=right
}else{
if sum==target{
//扩容并加入范围内的数组
ret=append(ret,nums[left:right+1])
}
// sum > target,删除一个较小的值,慢指针 left + 1
sum-=left
left++
}
}
return ret
}
优化写法:减少内存消耗
–执行用时:0 ms --内存消耗:2.2 MB
func findContinuousSequence(target int) [][]int {
var res, temp [][]int
left, right := 1, 2
sum := 3
max := target>>1 + 1
for left < right && right <= max {
if sum < target {
right++
sum += right
} else {
if sum == target {
temp = append(temp, []int{left, right})
}
sum -= left
left++
}
}
for _, v := range temp {
var s []int
//装填范围内的数字
for i := v[0]; i <= v[1]; i++ {
s = append(s, i)
}
res = append(res, s)
}
return res
}
解法二:暴力遍历累加法
–执行用时:4 ms --内存消耗:4.7 MB
func findContinuousSequence(target int) [][]int {
max := target >> 1 + 1
nums := make([]int,max)
ret := make([][]int,0)
for i,_:=range nums{
nums[i]=i+1
}
for i:=0;i<len(nums);i++{
sum:=nums[i]
for j:=i+1;j<len(nums);j++{
sum=sum+nums[j]
if sum==target{
ret=append(ret,nums[i:j+1])
}else if sum>target{
break
}
}
}
return ret
}