1. 一般子串问题:求一个串中满足某种条件的子串
1)如果所求子串的条件是一个值,比如sum,则考虑子段问题,注意这样一个性质,子段= 前缀差,子段和=前缀和的差,
vector<int> subarraySumClosestToZero(vector<int> nums){
// write your code here
if (nums.empty()) return vector<int>();
vector<pair<int,int>> prefixSum;
prefixSum.push_back(make_pair(0, -1));
for (int i = 0;i < nums.size(); ++i)
prefixSum.push_back(make_pair(nums[i] + prefixSum.back().first, i));
sort(prefixSum.begin(), prefixSum.end());
int minDiff = INT_MAX, start = 0, end = 0;
for (int i = 1; i < prefixSum.size(); i++) {
if (abs(prefixSum[i].first - prefixSum[i-1].first) < minDiff) {
minDiff = abs(prefixSum[i].first - prefixSum[i-1].first);
start = min(prefixSum[i].second, prefixSum[i-1].second) + 1;
end = max(prefixSum[i].second, prefixSum[i-1].second);
}
}
return vector<int> {start, end};
}
一个经典题,求01串中最大的0和1个数相等的字串
解法:0看作-1, 1看作1,等于是求最长的和为0的子段,转化成前缀和数组后,求相等的两个值,index距离最远的那两个。
2)如果满足满足滑动窗口的条件,滑动窗口法。
3)回文子串等不满足1),2)的,dp的方向考虑
4)暴力,但注意不是枚举所有子串(O(n^2))而是枚举终点。
2. 两个串中子串问题,或者一个串中多个子串问题
LCS: f[i][j] = f[i-1][j-1]+1 (s[i-1]==t[i-1]) or 0
LRS: 后缀数组法,计算后缀数组,排序,相邻元素求最长前缀