十一假期结束了,国庆天里幸福的脚步声、愉快的欢笑声、懒觉的打鼾声都再也和你没什么关系。别想这些了,收收心,好好刷几道算法题吧。
01、题目示例
一道很简单的题目~
题目:和为 s 的连续正数序列 |
---|
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。 |
示例 1:
输入:target = 9
输出:[[2,3,4],[4,5]]
示例 2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
02、题目分析
特别提醒:题解只是给你提供一个思路,真正的提高,取决于 coding 的过程。大量的练习,忍受难受的过程,才能真正的进步!
这个题目比较简单,典型的一道滑动窗口的题目。如果对滑动窗口陌生,可以系统学习下方题解:
万字长文!滑动窗口看这篇就够了!
假若我们输入的 target 为 9,大脑中应该有下面这么个玩意:
![9c007dc27b4469e78c6f5626fd6307a0.png](https://i-blog.csdnimg.cn/blog_migrate/5dc9ab5ee7be669e50d75d4a6ce99413.png)
然后我们通过左右指针来维护一个滑动窗口,同时计算窗口内的值是否是目标值:
![90a7fef2c89bb04fa3a1089bed5b4ac1.png](https://i-blog.csdnimg.cn/blog_migrate/dd3c63fde05545d15d228281b61ca316.png)
如果窗口的值过小,我们就移动右边界。
![aad355f92f4301b0e2c6456eec83df61.png](https://i-blog.csdnimg.cn/blog_migrate/d791d5ba4cfd35a2ca5ef046377024a5.png)
如果窗口的值过大,我们就移动左边界。
![a26b9f070202fc50c715b1a80acb079f.png](https://i-blog.csdnimg.cn/blog_migrate/7a7de7104da4e9401ea35943ba61a223.png)
剩下的就是反复上面的操作就可以了。到这里分析过程看似结束了。但是我们可以观察出一丢丢规律,用来优化我们的算法。对于任意一个正整数,总是小于它的中值与中值+1的和。为了让大家直观,用下图举例:
![099f51467cfed2fe819dd982a30ecd19.png](https://i-blog.csdnimg.cn/blog_migrate/94aec2c2e6e8734d2185bb9acfae75de.png)
比如这里的100,就一定小于50+51,换成其他数也一样。换句话说,一旦窗口左边界超过中值,窗口内的和一定会大于 target。
根据分析,得到题解:(好久没给 Go 语言的示例了,刻意把代码写的比较简单,没有用啥骚操作哈)
//go
func findContinuousSequence(target int) [][]int {
result := make([][]int, 0)
i := 1
j := 1
win := 0
arr := make([]int, target)
for i := range arr {
arr[i] = i + 1
}
for i <= target/2 {
if win win += j
j++
} else if win > target {
win -= i
i++
} else {
result = append(result, arr[i-1:j-1])
win -= i
i++
}
}
return result
}
同时也给一个java版本的:
//java
class Solution {
public int[][] findContinuousSequence(int target) {
List<int[]> res = new ArrayList<>();
int i = 1;
int j = 1;
int win = 0;
while (i <= target / 2) {
if (win win += j;
j++;
} else if (win > target) {
win -= i;
i++;
} else {
int[] arr = new int[j-i];
for (int k = i; k arr[k-i] = k;
}
res.add(arr);
win -= i;
i++;
}
}
return res.toArray(new int[res.size()][]);
}
}
03、继续优化
本题使用滑动窗口进行求解,是期望给出一种通用解法。有很多基础差的同学,并不能每道题目都玩出来骚操作。不过本题除了常规的滑动窗口之外,其实还有数学法,递推法等多种解题思路。比如我们可以用 等差数列求和公式 一步解答,大家可以下去自行思考一番~
所以,今天的问题你学会了吗,给小浩一个三连吧~
![214748d4fc72f51f7eaadc73c05a6e39.png](https://i-blog.csdnimg.cn/blog_migrate/f3932d013ea8ea93cce5f05608d6a6db.png)
我把一千本开源电子书,以及我写的 140 多篇算法图解,进行了汇总。下方扫码回复【资源】就可以全部下载 !!!
![6083d8aac0b0babefaab253dff6a047a.png](https://i-blog.csdnimg.cn/blog_migrate/9e6e37d14ef1f6a55e062b9ccc601ae2.png)
内容展示: