Summer的小少年

常用算法(二)

续 常用算法(一)

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

五,动态规划

适用条件

  • 问题的解可由子问题的解组合而成;
  • 子问题有重叠,会被重复求解;
  • 无后效性。某阶段的状态一旦确定,则此后过程的演变不再受此前各种状态及决策的影响。例如钢条切割问题。当n=3的最佳方案求出之后,计算n=4时的最佳方案时不会再影响到n=3的最佳方案的结果了。又例如最大子数组的和问题,当P[i]求出之后,在计算P[i+1]时,不会改变P[i]的值。
  • 经常用于求最优解,或求完成某种任务的方法个数

解题步骤

  1. 求出递推式(求递推式可以采用自顶向下的选择法,也可采用自底向上的递推法。)
    • 选择法(推荐,更直观):主问题上做一个选择,问题变化成一个或多个子问题。常用于问题能够被化为多个子问题的情况:如干活(连续两天干活后必须休息一天)。又如best time to buy and sell a stock IV
    • 递推法:假设子问题已经被解决,主问题在子问题的基础上如何解:常用于问题能够被化为一个子问题的情况。(最大子数组的和)
  2. 第二步:自底向上,用一个数组保存子问题的求解结果。或自顶向下,用cache保存结果 

动态规划的变形

有些问题难以做到直接使用动态规划求解,需要一个转换。例如最大子数组的和问题。如果希望直接用动态规划,令P[i]为子数组0到i的最大子数组的和,则难以推导出P[i+1]和P[i]的关系。所以,令P[i]为子数组0到i的,以i为右边界的最大子数组的和,则可以容易推导出P[i+1]与P[i]的关系。

  • Maximum sub array
  • Longest palindrome string
  • Unique Binary search tree

有些题中,为了求得最终结果,需要规划多个递推式。

  • Maximum product subarray 此题以i为右边界的子数组的最大乘积需要依赖于以i-1为右边界的子数组的最大(正数)和最小乘积(负数)。负数x负数=正数
  • Best time to buy and sell stock IV 两递推式:前i天最多允许j次交易的全局最优解g[i][j]和前i天最多允许j次交易,且最后一次交易发生在第i天的局部最优解l[i][j]

六,贪心法

适用条件

  • 可用动态规划解的问题。
  • 寻优问题
  • 当前问题做出一个最优选择之后,转化为唯一的一个子问题,然后递归求解
  • 动态规划中,做出的每一个选择,依赖于子问题的解。贪心则不依赖子问题的解,它只是当前最优的方案。例如Jump Game。如从正向开始求解,令P[i]为从i处到目的地所需要的最少步数,则这是个动态规划的方案。因为从i出走出的第一步到哪个位置依赖于子问题P[j] ( j是>i且i能到达的所有位置)的值。如从终点反向开始求解,第一步为能到达终点的最远的一个位置,然后递归求解,则是贪心方案,因为当前选择并未依赖任何子问题的解。事实上,子问题尚未求解。

解题步骤

  自顶向下,用递归的方式

前提

  需要证明这个贪心的选择能够得到最优解

题例

  • Jump game
  • Meeting room

七,排序应用

全排序

预排序,应用于数组,和双指针算法一起工作
  • Container with most water
  • 2 sum
强制排序,适用于排除重复解
  • Permutation II
  • Subsets II
预排序,可以将o(n2)的算法降为o(nlogn)
  • Merge Intervals

部分排序

分割,应用于数组,适用于不需要全部排序,然后需要找到某个位置的场合
  • Find k biggest number
基数排序及其它,适用于时间复杂度要求较高的场合 o(n).
  • Maximum Gap

posted on 2018-12-22 14:30  cesar_lu  阅读(167)  评论(0编辑  收藏  举报

导航