基本思路-算法题解法系列一

第一篇博客~~~

由于近期一直在leetcode上刷题,于是就想到找时间归纳一下算法题的一些共通的解题思路。诚然,算法这东西确实是艰深无比,有时候一种合适的解法的产生需要灵感的迸发。但是,它还是有一些规律性的东西可寻。在这里,我就将算法题做个大致的分类,并提供每种类型的题目的可能的解法。

首先,先列出解题应该具有的一个基本的思维过程。如下:

  • 以前是否做过类似题目?(回忆,并比较)
  • 用几种常用算法(二分,动态规划,穷举,排序等)尝试。如,求某种选择的个数问题,常用动态规划法。而问题容易推导出和子问题的关系的,可用分治,动态规划。
  • 分析题干的数据结构的特点,有时会提示可能的解法。例如有序数组经常和二分联系,链表经常需要单次或多次遍历,等。还有一点很重要,要充分利用所有的题干提供的条件。有时题干条件能够提示解题方法。(trie)
  • 如上述都无效,则使用下面的更一般的适用于所有题目的通用解法。
    • 若题目能容易地得到一个朴素的算法,则可以从这个朴素算法入手,得到时间(空间)复杂度。然后看看是否有优化的可能。优化方法有下面几种:
      • 减少不必要的计算和重复计算降低时间(空间)复杂度,通过强制排序等方法。
      • 减少空间复杂度:将中间数据存储在已有数据结构中 (Set zeroes )
      • 能否选择更高效的数据结构(例如:判断对象是否存在或计数,用哈希表;集合基本有序求最值,用堆;求字符串的前缀,用trie;对区间进行动态查询和插入,用区间树)
      • 有时可先去掉题目的某些限制条件,得到朴素算法后,从此条件入手,优化算法。
    • 能否对题干的某一个部分进行简化,如:去掉一些限制条件,或者,将二维情况变为一维的情况。从而容易发现可能的解法。(Candy,将给定的rating数组简化为单调增或者单调减的数组,则容易得到解法。然后,再一般化题干,对解法进行一般化。)
    • 分析解(包括用于求解的中间数据)的结构和特点,推测可能的解法。比较最优解与周围解的不同之处。手动得到解的一部分,观察解的特点。此方法经常用于求解搜索类的问题。(maximum rectangle, bulb switcher,super ugly number 解空间是能被指定素数集合整除的数列,该数列是多个这样的数列:被某个素数整除的数列 的合并排序所得。故想到用堆实现;Minimum window substring 解空间是满足一定条件的一个子串,该子串的边界字符必在T中!想到双指针或动态规划。又:动态规划难以推导出递推公式,故采用双指针尝试。)
  • 其他特殊题型的解法
    • 有些算法题要求设计一个类以及多个函数。比如:用已有的数据结构去实现另一个。用那个给定的数据结构和一两个变量辅助,一起实现所需要的功能。此类题目我称之为设计型算法,经常无法在一个函数中将问题解决,需要在多个函数中一起配合实现。( Using queue to implement Stack; Peeking Iterator 无法仅在peek中实现,需要在peek,next一起配合实现)

以上就是我归纳的算法题的通用解法。后续会对常用的算法作一些总结。

  

猜你喜欢

转载自www.cnblogs.com/cesarlu/p/9494436.html
今日推荐