常用算法(一)
续首篇,开始归纳整理常用的算法大类。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
一,穷举法
特点及适用范围
暴力寻找所有的解,一般用递归求解。解题步骤
- 求出问题的解的第一步
- 求出经过第一步限制之后的子问题的解。子问题可能得不到解,此时说明第一步的求解不成功,退回第一步,重新求解(需要将已经试探过的解排除)。
- 将第一步的解和子问题的解合并,就可得到整个问题的解。
题例
- N Queens
- Sudoku
- Restore IP addresses
- Permutations
- Subsets
关键点
穷举法或动态规划法求一些组合个数问题经常需要去掉重复的解。解决方法:- 强制排序,一是能发现重复值,二是能按照特定顺序求解。即:当前的选择和递归之后的选择之间存在某种顺序关系。例:
- Combinations 当前从数组中任意选择一个数,递归的调用只对此数后面的子数组进行调用,保证所有得到的组合集合中的组合的数字顺序与原数组匹配
- 郊游问题 为学生添加序号,当前只对序号最前的学生进行匹配选择。保证所有得到的匹配集合中的匹配出现的顺序按照学生序号排序。
- 将引起重复的几个选择放在一起,多个steps合并成一个选择求解,而不是递归地对所有的单个step求解。例:
- 多连骨牌,递推关系不是在n个骨牌的解与n-1个骨牌的解(每个step增加一块)之间进行,因为如果这样做的话,无法排除重复的形状。将每一行作为一个step整体考虑,可以避免重复。
二,双指针(滑动窗口)
分类
对向双指针收缩,应用于数组,适用于求有序数组中满足条件的对
- 2sum
- Container with most water
应用于数组,适用于分割partition操作
- Sort colors
- Quick sort
同向双指针,适用于求一个满足条件的子范围
- Minimum window substr
- Substr with concatenation of all words
- Find continuous integers that sums to a specified value
应用于链表
- Remove nth node from end of list
- Find first node where two lists start to intersect
三,二分查找
特点及适用范围
- 适用于在有序数组中查找满足特定条件的元素
- 适用于在整数序列(由于整数也可被认为是有序数组)中查找,完成一些数学功能
题例
- Search insert position
- Search for a range
- Sqrt()
- Divide two integers
四,分治
特点及适用范围
- 问题的解可由子问题的解组合而成。分成子问题后,将子问题的解合并的算法比解原问题简单
- 子问题互不相关
- 子问题互不重叠
解题步骤
- 将问题分成一个或多个子问题(经常是两个)递归求解
- 将子问题的解合并
- 实现递归函数的收敛状态
分类
两个子问题
- Merge intervals
- Merge k sorted lists
一个子问题
- Median of two sorted arrays