【算法】滑动窗口和前缀和
遇到了题目 437.路径总和 III ,学习一下滑动窗口和前缀和。重点是前缀和。
滑动窗口
参考链接:
滑动窗口主要用来处理连续问题。比如题目求解“连续子串 xxxx”,“连续子数组 xxxx”,就应该可以想到滑动窗口。能不能解决另说,但是这种敏感性还是要有的。
模版代码
给出窗口指针 left,right 表示窗口的左右顶点。
固定窗口代码模版
left 初始化为 0
初始化 right,使得 right - left + 1 等于初始窗口大小
同时移动 left 和 right
判断窗口内的连续元素是否满足题目限定的条件
4.1 如果满足,再判断是否需要更新最优解,如果需要则更新最优解
4.2 如果不满足,则继续。
可变窗口代码模版
left 和 right 初始化为 0
r 指针移动一步
判断窗口内的连续元素是否满足题目限定的条件
3.1 如果满足,再判断是否需要更新最优解,如果需要则更新最优解。并尝试通过移动 l 指针缩小窗口大小。循环执行 3.1
3.2 如果不满足,则继续。
例题
前缀和
参考链接:
问题引入
思考一个问题:求一个数组的所有连续子数组。
连续子数组指的是索引连续的子数组。例如,数组 [1,3,4] 的连续子数组包括 [1], [3], [4], [1,3], [3,4], [1,3,4] 。
其中一种思路是,令 $ f(i) $ 表示以索引 $ i $ 结尾的子数组的个数。那么显然,子数组的总个数就等于 $ \sum\limits_{i=0}^{n-1}f(i) $ (n 表示数组长度)。同时,我们也能发现,$ f(i+1) = f(i) + 1 $ 。
这里我们就发现了前缀的概念:如果我们能够求出以索引 i 结尾的所有子数组,那么我们就能顺利地求出以 i+1 结尾的所有子数组。
例题
leetcode 437.路径总和 III
给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
示例 1:
1 | 输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8 |
示例 2:
1 | 输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 |
思路:
该问题同样满足前缀和。以示例 1 的树为例,我们考虑以结点 5 为结束结点的路径,显然有 [10,5] 和 [5] 。此时,我们很容易得知,以结点 3 为结束结点的路径有:
[10, 5, 3] = [10, 5] + 3
[5, 3] = [5] + 3
[3]
因此,只要我们得到了以父结点为结尾的路径,我们能立刻得到以其子结点为结尾的路径。根据这种思路,采用先根序遍历树即可得到所有路径。
1 | class Solution: |