3 无重复字符的最长子串【中】

思路:感觉有点难的亚子..因为重复出现的位置无法预料,那么下一次寻找的开始位置如何确定,难道用暴力解法依次遍历?首次,如何判断和记录重复,每次用一个哈希表?
1  | class Solution {  | 
- 用滑动窗口替代复杂度为$O(n^2)$的暴力解法,核心是要记录下重复位置用于窗口滑动
 - 定义一个 map 数据结构存储 (k, v),
Map<Character, Integer> map = new HashMap<>();其中 key 值为字符,value 值为字符位置 +1,加 1 表示从字符位置后一个才开始不重 复, 同时存位置的方法可以从始至终只用一个哈希表即可 start = Math.max(map.get(alpha), start);start取更大的值,一方面start保证不会后退;另一方面value 值为重复字符上一次的位置 +1,下一次的最长必不包含本次重复的这一段,故直接跳到本次重复第一个字符的下一位置
+无论是否更新 start,都会更新其 map 数据结构和结果 ansans = Math.max(ans, end - start + 1);- 字符串方法:string.length() string.charAt(pos)
 - hashmap方法:hashmap.containsKey(key) hashmap.put(key,value)
 - Math.max(value1,…)
 - 哈希表还可以直接用int[26] 来代替
 
时间复杂度:$O(n)$
空间复杂度:$O(min(n,m))$ m为字符集大小
5 最长回文子串【中】

思路:一般来说回文可以用栈判断,但这是一个动态问题。如果用栈的话,什么时候弹出其实感觉比较难判断。不如用双指针?
暴力解法
1  | public boolean isPalindromic(String s) {  | 
- 用双指针判断回文
 
时间复杂度:$O(n^3)$
空间复杂度:$O(1)$ 
暴力破解优化1
1  | public String longestPalindrome(String s) {  | 

boolean[][] P = new boolean[length][length]存储判断结果矩阵- 最外层按长度来遍历
 - 长度为 1 和 2 的单独判断,然后基于其向两边拓展
 
时间复杂度:$O(n^2)$ 空间换时间
空间复杂度:$O(n^2)$  — 可以优化
暴力破解优化2
1  | public String longestPalindrome7(String s) {  | 
- 下一对角线的遍历只用到了相邻的更长对角线的结果,那么用长度为n的数组,结果不断覆盖
 - 根据递推公式,采用倒序遍历
 - j-i+1为字符串长度len,len为1或者2,所以len<3即j-i<2,而用一维数组存储结果时len=1都为ture,所以长度为3只需要判断两端字符是否相等
 

时间复杂度:$O(n^2)$ 空间换时间
空间复杂度:$O(n)$
动态规化
再用一个逆序字符串,转化为最长公共子串问题,但是效率并不太高
中心扩展法
1  | public String longestPalindrome(String s) {  | 
- 从一个字符开始扩展,或者从两个字符之间开始扩展,所以总共有 n+n-1 个中心
 start = i - (len - 1) / 2;end = i + len / 2;确定回文字符串的起止位置
时间复杂度:$O(n^2)$
空间复杂度:$O(1)$ — 充分利用了回文对称的特点
Manacher’s 算法
1  | public String preProcess(String s) {  | 
- 加特殊字符 “#” 使字符串统一为奇数长度
 - 用一个数组 P 保存从中心扩展的最大个数,而它刚好也是去掉 “#” 的原字符串的总长度;用 P 的下标 i 减去 P [ i ],再除以 2,就是原字符串的开头下标了
 - 相比于中心拓展法,利用了前半部分的对称信息; 对称时分三种情况来讨论
 
时间复杂度:$O(n)$
空间复杂度:$O(n)$ 
6 Z字形变换【中】

思路:竖向和斜向的字符数相等,如何建立输出顺序与排列方式的联系?每 n+n-2 个数视为一组,这组元素以除最高和最低点外,每行有两个数。可以建立规律,后面的情况+模即2n-2
找规律
1  | class Solution {  | 
- StringBuilder 是一个可变对象,可以预分配缓冲区,这样,往StringBuilder中新增字符时,不会创建新的临时对象,支持链式操作。有.append(s) .insert(pos,s) .toString() 方法
 
时间复杂度:$O(n)$
空间复杂度:$O(n)$ 
按行排序
1  | class Solution {  | 
- 用字符串数组来存储,+号直接拼接在后面
 - 用向下或向右来控制row是增还是减
 loc == 0 || loc == numRows - 1每到顶点时变换方向
时间复杂度:$O(n)$
空间复杂度:$O(n)$ 
8 字符串转换整数(atoi)【 中】

思路:寻找第一个非空格字符,没找到不转换。找到后若不是正负号也不是数字,不转换。若是正负号,记录符号,接着计算数值,计算数值:可以用栈? 连续数值之后的字符可以忽略。计算出整数值之后还要判断是否在有效区间内,溢出返回最大或最小值。
1  | class Solution {  | 
- 注意判断条件,哪些是可以并列的,以及先后顺序
 - 直接用ret迭代,不用栈
 - 32 位有符号整数范围 -2147483648 ~ +2147483647
 - 如果没有+号这个溢出判断是不是有什么问题?范围缩小位?
 
时间复杂度:$O(n)$
空间复杂度:$O(1)$ 
10 正则表达式匹配【难】

思路:首先这是一个匹配问题,由于正则的存在使得模式串有极多的可能性,如何确定一某合理的比较顺序?若是字母,判断对应位是否相等?不等为false。为.继续匹配下一位。为*时,若前面无字符,继续;有字符,先移动继续移动目标串直至不为该字符,特别的若该字符为.,若已处于模式串末尾返回true;否则返回false
1  | class Solution {  | 
+return matchCore(s,sIndex+1,p,pIndex)  || matchCore(s,sIndex,p,pIndex+2);精髓