简记
关于算法:n数之和模板,主要是基于两数之和的改造,在两数之和的基础上做递归拆解子问题,每次加上循环的nums[i].。
n数之和的简单思路:先对数组进行排序,使用双指针思路实现,将n数之和拆解为两数之和的模板进行递归,每次递归时添加一个子答案。
关于最长回文子串:
简化问题:从字符串中心向两边遍历,实现双指针遍历效果,考虑两种情况回文子串为奇数长和偶数长,三者比较返回最大值即可。
回文子串判断:l,r l>=0 时,向左遍历, r<s.length(), 二者值相同时继续便遍历,最终返回s.substring(l+1, r)。
substring函数截断时为左闭右开截断。
关于原地删除有序数组中的重复项:
主要使用快慢指针方法,维护一个窗口,[slow,fast)。当两个位置上的值不相等时,将fast位置的值加入窗口,slow向后移动;相同时,仅移动fast。
思路实现与滑动窗口类似。 LeetCode26 80
75.颜色分类
借助双指针思路,维护两个区间 [0,p0) 是元素 0 的区间,(p2, nums.length - 1] 是 2 的区间,使用指针p来遍历数组。
88.合并两个有序数组
要求保存至数组一中,则考虑从数组尾部开始遍历,每次从两个数组的尾部取最大值。当有一个数组遍历至头部后结束,此时数组二可能未结束需要单独考虑。
14.最长公共前缀
solution:
class Solution {
public String longestCommonPrefix(String[] strs) {
String s0 = strs[0];
for (int j = 0; j < s0.length(); j++) {
char c = s0.charAt(j);
for (String s : strs) {
if (j == s.length() || s.charAt(j) != c) {
return s0.substring(0, j);
}
}
}
return s0;
}
}
滑动窗口模块:
简单的模板:
// 滑动窗口算法伪码框架
void slidingWindow(String s) {
// 用合适的数据结构记录窗口中的数据,根据具体场景变通
// 比如说,我想记录窗口中元素出现的次数,就用 map
// 如果我想记录窗口中的元素和,就可以只用一个 int
Object window = …
int left = 0, right = 0;
while (right < s.length()) {
// c 是将移入窗口的字符
char c = s[right];
window.add(c)
// 增大窗口
right++;
// 进行窗口内数据的一系列更新
...
// *** debug 输出的位置 ***
// 注意在最终的解法代码中不要 print
// 因为 IO 操作很耗时,可能导致超时
printf("window: [%d, %d)\n", left, right);
// ***********************
// 判断左侧窗口是否要收缩
while (left < right && window needs shrink) {
// d 是将移出窗口的字符
char d = s[left];
window.remove(d)
// 缩小窗口
left++;
// 进行窗口内数据的一系列更新
...
}
}
}