Summer的小少年

常用算法(一)

续首篇,开始归纳整理常用的算法大类。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

一,穷举法

特点及适用范围

暴力寻找所有的解,一般用递归求解。

解题步骤

  1. 求出问题的解的第一步
  2. 求出经过第一步限制之后的子问题的解。子问题可能得不到解,此时说明第一步的求解不成功,退回第一步,重新求解(需要将已经试探过的解排除)。
  3. 将第一步的解和子问题的解合并,就可得到整个问题的解。

题例

  • 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

四,分治

特点及适用范围

  • 问题的解可由子问题的解组合而成。分成子问题后,将子问题的解合并的算法比解原问题简单
  • 子问题互不相关
  • 子问题互不重叠

解题步骤

  1. 将问题分成一个或多个子问题(经常是两个)递归求解
  2. 将子问题的解合并
  3. 实现递归函数的收敛状态

分类

两个子问题
  • Merge intervals
  • Merge k sorted lists
 
一个子问题
  • Median of two sorted arrays

 

posted on 2018-10-03 13:34  cesar_lu  阅读(73)  评论(0编辑  收藏  举报

导航