Skip to content

Latest commit

 

History

75 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

算法记录

Math

7. 整数反转

通过对 10 求余和除以 10,获取最后一位数字,累加到结果中。累加前需要判断溢出

9. 回文数

反转一半数字,判断是否与另一半相等(注意位数的奇偶),该方法可以防止溢出

11. 盛最多水的容器

双指针,贪心算法。从左右向中间收缩,每次收缩较低的一边。原因是收缩时间距在变小,如果不改变较低的一边,那收缩后面积一定会更小

12. 整数转罗马数字

模拟,预先从大到小列出所有罗马数字组合,从大到小逐步减

13. 罗马数字转整数

模拟,从左到右依次转为数字,需要处理左边数字比右边数字小的情况

15. 三数之和

排序+双指针,选定第一个数,其他两数通过双指针从左右两侧遍历。利用排序进行剪枝优化

16. 最接近的三数之和

解法同三数之和,排序+双指针。根据三数和与 target 之间的最小差选择结果

18. 四数之和

解法类似三数之和,排序+双指针,选定第一个数和第二个数,双指针遍历其他两数

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

快慢指针,快指针找到不重复的数,赋值给慢指针

27. 移除元素

(1) 快慢指针,快指针找到不为 val 的数,赋值给慢指针

(2) 快慢指针优化,快指针从右向左,赋值给慢指针为 val 的位置

29. 两数相除

用减法模拟乘法,不断循环 1) 减除数,2) 除数翻倍,直到被除数小于需要减去的数,再重新从除数开始减

31. 下一个排列

等价于找到下一比当前数字大的数,即把后面的大数与前面的小数交换,且保证交换后的结果最小。需要从右向左,找到第一个比后面数字小的数字 x,把 x 与后面比它大的最小数字交换。交换后,后续序列一定为倒序排列,需要反转为正序

41. 缺失的第一个正数

原地哈希,首先交换整数 x 到数组中 x-1 位置,随后遍历找到第一个位置不符合的数

50. Pow(x, n)

递归,快速幂

String

3. 无重复字符的最长子串

(1) 滑动窗口法,借助 map 判断重复字符,并且移动左边界

(2) 滑动窗口法,与解法一相同,但是不删除 map 中元素,而是比大小

5. 最长回文子串

中心扩展法,每个字符向左右两侧遍历,找到最长回文串

6. Z 字形变换

数学推理,行数变化有周期性

8.字符串转换整数 (atoi)

按规则转换,每次新增数字前都需要判断是否会溢出

10.正则表达式匹配

动态规划,dp[i][j] 表示 s 前 i 个字符 是否能被 p 前 j 个字符 匹配。重点:* 号分为匹配字符和不匹配字符分析

14. 最长公共前缀

挨个字符比较,直到结束或者遇到不同字符

28. 找出字符串中第一个匹配项的下标

(1) 暴力匹配

(2) KMP:待实现

30. 串联所有单词的子串

滑动窗口+哈希表,通过哈希表记录滑动窗口中单词与给定词组的个数差

32. 最长有效括号

(1) 借助栈匹配括号,找最长子串

(2) 使用两个常数,记录左括号和右括号数量,相等时即为有效。需要正序遍历和反序遍历各一次

(3) 动态规划,dp[i] 表示位置 i 结尾的字符串中,最大有效括号的长度

38. 外观数列

(1) 递归

(2) 迭代

43. 字符串相乘

模拟,列竖式,num1 的第 i 位与 num2 的第 j 位相乘,结果位于 i + j 和 i + j + 1 位

44. 通配符匹配

动态规划,dp[i][j] 表示 s 前 i 个字符是否能被 p 前 j 个字符匹配。重点:* 号分为匹配字符和不匹配字符分析

49. 字母异位词分组

对字符串的字母计数,计数结果一致的为异位词

List

19. 删除链表的倒数第 N 个结点

快慢指针,快指针先遍历 N 个结点

21. 合并两个有序链表

(1) 递归,比较头节点,选出最小的

(2) 迭代

23. 合并 K 个升序链表

(1) 递归,比较头节点,选出最小的

(2) 分治,k 个链表分为两份合并

(3) 优先队列,插入全部头节点,每次取出最小节点,并插入其下一个节点

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

(1) 借助栈,先入后出,反序相邻节点

(2) 递归

(3) 迭代

25. K 个一组翻转链表

(1) 借助双端队列,前面的每 k 个元素先入后出,反序节点,最后不足 k 个元素先入先出,保持顺序

(2) 模拟,每 k 个节点,执行一次反转链表

Binary

4. 寻找两个正序数组的中位数

(1) 双指针,从小到大递增,直到达到中位数位置

(2) 二分法,问题转化为给定两个有序数组,求第 k 小的数

(3) 二分遍历较小数组的分割线位置

33. 搜索旋转排序数组

二分法,先判断哪半边区间有序,再判断 target 是否在有序区间内

34. 在排序数组中查找元素的第一个和最后一个位置

二分法,查找两次,一次找左边界,一次找右边界。重点在于 nums[mid] == target 时的边界处理

35. 搜索插入位置

二分法

Backtrack

17. 电话号码的字母组合

回溯,遍历所有组合

22. 括号生成

回溯,根据左括号数量,判断下一个字符

37. 解数独

回溯,在每一个空格上,回溯遍历每个合法的数字

39. 组合总和

排序+回溯,需要结合排序结果,避免选择重复的组合

40. 组合总和 II

排序+回溯,需要结合排序结果,且跳过相同的元素,避免选择重复的组合

46. 全排列

回溯,借助交换位置生成全排列

47. 全排列 II

回溯,借助交换位置生成全排列,需要剪枝避免重复

51. N 皇后

(1) 回溯,使用二维数组记录棋盘,判断行,列,对角线是否可以放置皇后

(2) 回溯,使用位运算记录行,列,对角线是否可以放置皇后

52. N 皇后 II

与 “51. N 皇后” 完全一致

(1) 回溯,使用二维数组记录棋盘,判断行,列,对角线是否可以放置皇后

(2) 回溯,使用位运算记录行,列,对角线是否可以放置皇后

Matrix

36. 有效的数独

(1) 遍历,借助二维数组,判断行、列、块内是否有重复数字

(2) 遍历,借助一维数组 + 位运算,判断行、列、块内是否有重复数字

48. 旋转图像

先转置,后翻转每一行

Stack

20. 有效的括号

使用栈,判断括号有效性

42. 接雨水

(1) 双重遍历,找到每根柱子左右侧最高的柱子高度,计算每根柱子的接水量

(2) 动态规划,使用数组记录每个柱子左右侧最高的柱子高度

(3) 双指针,从左右向中间聚拢,每次计算较低一侧的接水量

(4) 单调栈,保持栈内柱子的高度单调递减,每次出栈计算接水量

Greedy

45. 跳跃游戏 II

贪心,每次选择最远的位置

Dynamic Programming

53. 最大子数组和

(1) 动态规划,dp[i] 代表以 nums[i] 结尾的最大连续子数组和, 满足 dp[i] = max(dp[i-1] + nums[i], nums[i])

(2) 动态规划 + 空间优化,由于 dp[i] 只与 dp[i-1] 有关,因此可以只用一个变量 dp

(3) 分治法,对于任意区间,维护以下四个量,在合并区间时进行更新

  • iSum: 区间和
  • lSum: 从区间左端点出发的连续子数组最大和
  • rSum: 以区间右端点出发的连续子数组最大和
  • mSum:区间内的连续子数组最大和

3524. 求出数组的 X 值 I

(1) 动态规划,依据前一个元素结尾的子数组的余数数组,更新下一个元素结尾的子数组的余数数组

(2) 动态规划,在思路一的基础上,优化空间复杂度

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages