Time-space-tradeoff: 以空间换时间
一、当存在overlapping subproblem的时候,就需要考虑"以空间换时间"来提升性能。
二、当超时的时候,就需要考虑如何以空间换时间。
Dynamic programming / 动态规划
这是最最典型的以空间换时间,将子问题的解保存下来,在下面文章中,有着非常好的分析:
1、labuladong 动态规划设计之最长递增子序列
数组算法中的以空间换时间
下面描述的四个数组相关的算法,其实存在着如下的相似点:
1、区间在扩大
一、min、max
股票买卖问题
求一个不断扩展的区间中的min、max,可以通过维护min、max而实现,这在 labuladong LeetCode 股票问题的一种通用解法 中,进行了详细的说明。
它可以看做是 "以空间换时间",将 O(n^2) 穷举 转换为 O(n) 穷举。
二、最大子数组和问题
这在 Expert-labuladong\1-动态规划系列\1.2-子序列类型问题\最大子数组
章节中,进行了讨论。最最常规的实现方式是O(n^3),通过观察递归关系,记录子问题的解,然后根据递归关系,获取更大问题的解,可以将其转换为O(n^2)。
找数算法、hash map以空间换时间
LeetCode 1711. 大餐计数
使用hash map保持数字出现的次数。
NOTE:
在很多的地方都使用了这种用法,比如:
1、滑动窗口
LeetCode 1. 两数之和
以空间换时间
滑动窗口以空间换时间
参见 labuladong 我写了套框架,把滑动窗口算法变成了默写题 :
/* 滑动窗口算法框架 */
void slidingWindow(string s, string t) {
// 预处理字符串
unordered_map<char, int> need, window;
for (char c : t) need[c]++;
int left = 0, right = 0;
int valid = 0;
while (right < s.size()) {
// c 是将移入窗口的字符
char c = s[right];
// 右移窗口
right++;
// 进行窗口内数据的一系列更新
...
/*** debug 输出的位置 ***/
printf("window: [%d, %d)\n", left, right);
/********************/
// 判断左侧窗口是否要收缩
while (window needs shrink) {
// d 是将移出窗口的字符
char d = s[left];
// 左移窗口
left++;
// 进行窗口内数据的一系列更新
...
}
}
}
预处理字符串-加速匹配
一、binary search 二分查找优化subsequence子序列匹配
labuladong 二分查找的妙用:判定子序列
LeetCode 392. 判断子序列 简单
二、KMP algorithm
三、滑动窗口
LeetCode 解数独
其中就用"以空间换时间"来进行优化。
Algorithms use memory to gain performance improvement
使用空间换取时间
https://www.sciencedirect.com/topics/computer-science/performance-gain
https://stackoverflow.com/questions/1898161/memory-vs-performance