1. two sum

原来想的是先一遍循环put, 再判断是否存在 target - nums[k]

这样会产生严重的问题, [2, 1] target=4 这样就会返回错误结果

最好的解决办法是 for each num -> check first than put

2. add two numbers

给出两个非空的链表用来表示两个非负的整数, 逆序方式存储. 如果将这两个数相加, 则会返回一个新的链表来表示他们的和. 除了0之外,这两个数都不会以0开头

eg (2 -> 4 -> 3) + (5 -> 6 -> 4) = (7 -> 0 -> 8) 342 + 465 = 807

结构可以从两个链表merge的过程修改, 还要处理进位 update 两个链表merge的结构还可以优化成一个while!

3. length of longest substring

eg. abcabcbb -> 3 bbbb -> 1 pwwkew -> 3 维护一个滑动窗口, left表示窗口左边界, right 表示窗口右边界 char[256] map 表示哈希表 arr[str[right]] > 0 -> 窗口滑动 map数量置0, 移动left, 重新计算res arr[str[right] == 0] -> 窗口滑动 put str[right], right++ 最后, 重新计算 res

5.最长回文子串

eg. babad -> bab or aba 遍历(2n-1)种中心点,分别向两边扩展,得出最大值. 难点在边界的计算

6.Z字形变换

将字符串从上到下, 从左到右(N字型排列) 1 7 13 2 6 8 12 14 3 5 9 11 15 4 10 16

可以找到规律,第一行间距是step=2n -2 第二行间距是 step - 2, 2, step - 2, 2 ... 第三行 step - 4, 4, step - 4, 4... 最后一行, step, step, step

一层循环遍历行数, 二层添加每行内容

7.整数反转

32位有符号整数,将每位反转 如果有数值溢出,返回0

用算术模拟进栈出栈 %10 取十进制最低位, /10 十进制右移 *10 十进制左移

8.实现atoi函数 (String to Integer)

对于溢出部分,采用最大 or 最小值 1.处理空格 2.处理符号 3.十进制移位,并处理溢出

9.回文数

判断一个int值是否是回文数 简单思路,转换成字符串再比较 better: 数值上反转可能会溢出,全部反转不可取 对于只反转一半的情况, 要排除一部分特殊值

10.正则表达式匹配

实现 .* 的匹配 s 可能为空, 有且只包含 'az' p 可能为空,有且只包含 a-z, ., *

11.盛最多水的容器

双指针,每次移动指针都计算一次最大面积,值最小的指针向中间移动

12.整数转罗马数字

贪心, 相当于找纸币 枚举所有原子的罗马数字标识符

#### 13.罗马数字转整数 枚举所有罗马数字的(原子)字符 map匹配

14.最长公共前缀

令最长前缀res为第一个字符串 遍历后面字符串,依次与res比较,每次循环得出一个新的res 中间如果出现res="", 直接返回"";

15.三数之和

n个整数数组nums, 判断是否存在 a,b,c 使 a + b + c = 0; 找出所有满足条件且不重复的三元组

首先对数组排序 遍历数据 双指针定位其余两个值 如何判断不重复?遍历数据时去重,双指针移动时去重

16.最接近的三数之和

给定一target,找出nums中的三个整数,使他们的和与target最接近. 假设每组输入只存在唯一答案 还是先排序,与三数之和不同的是,两个指针不会同时移动

17.电话号码的字母组合

回溯 遍历数字,并回溯 当遍历到的数字是最后一个时,加入结果集中

20.有效的括号

栈,左括号入栈,右括号判断是否和栈顶匹配

21.合并两个有序的链表

注意链表的移动细节

22.括号生成

回溯,记录剩余左括号和右括号个数 如果剩余右括号个数为0,添加并返回

如果有可匹配的左括号,添加匹配 如果有剩余的左括号,添加左括号

24.两两交换链表中的节点

先想循环不变式

26.删除排序数组中的重复项

原地删除并返回长度 双指针

27.移除元素

同理

28.实现StrStr()

for + for

better solution:KMP算法 每遇到一个字符,分为三个动作: 升级,降级,重置 如果匹配,则升级,如果当前状态是孪生词缀,并且匹配旧状态,降级 eg. aba -> b -> ab 否则重置