Algorithm Notes
  • Introduction
  • Search & Backtracking 搜索与回溯
    • Tree 与 BackTracking 的比较
    • Subsets, Combination 与 Permutation
    • Subsets & Combinations & Combination Sum
    • 枚举法
    • N 皇后 + 矩阵 Index Trick
    • Sudoku 数独 + 矩阵 Index Trick
    • Word Ladder I & II
    • Number of ways 类
    • DFS flood filling
    • Strobogrammatic 数生成
    • String 构造式 DFS + Backtracking
    • Word Pattern I & II
    • (G) Binary Watch
    • (FB) Phone Letter Combination
    • 常见搜索问题的迭代解法
  • String,字符串类
    • 多步翻转法
    • Substring 结构和遍历
    • Palindrome 问题
    • Palindrome Continued
    • String / LinkedList 大数运算
    • 序列化与压缩
    • 5/24 String 杂题
    • Knuth–Morris–Pratt 字符串匹配
    • Lempel–Ziv–Welch 字符串压缩算法
    • (G) Decode String
    • (G) UTF-8 Validation
  • Binary Tree,二叉树
    • 各种 Binary Tree 定义
    • LCA 类问题
    • 三序遍历,vertical order
    • Post order traversal 的应用
    • Min/Max/Balanced Depth
    • BST
    • 子树结构
    • Level Order traversal
    • Morris 遍历
    • 修改结构
    • 创建 / 序列化
    • 子树组合,BST query
    • 路径与路径和
    • NestedInteger 类
    • (FB) 从 Binary Tree Path 看如何递归转迭代
    • (FB) Binary Tree Path 比较路径大小
    • 比较好玩的 Binary Tree 概率题
  • Segment & Fenwick Tree,区间树
    • Segment Tree 基础操作
    • Segment Tree 的应用
    • Fenwick Tree (Binary Indexed Tree)
    • Range Sum Query 2D - Immutable
  • Union-Find,并查集
    • Union-Find,并查集基础
    • Union-Find, 并查集应用
  • Dynamic Programming, 动态规划
    • 6/20, 入门 House Robber
    • 7/12, Paint Fence / House
    • 6/24, 滚动数组
    • 6/24, 记忆化搜索
    • 6/24, 博弈类 DP
    • 博弈类DP, Flip Game
    • 6/25, 区间类DP
    • 6/27, subarray 划分类,股票
    • 7/2, 字符串类
    • Bomb Enemies
    • 8/2,背包问题
    • (G) Max Vacation
    • (11/4新增) AST 子树结构 DP
  • LinkedList,链表
    • 6/9, LinkedList,反转与删除
    • 6/11, LinkedList 杂题
    • (FB) 链表的递归与倒序打印
  • LinkedIn 面经,算法题
    • 6/17, LinkedIn 面经题
    • 6/28, LinkedIn 面经题
    • 7/6, LinkedIn 面经
    • Shortest Word Distance 类
    • DFA Parse Integer
  • Two Pointers,双指针
    • 3 Sum, 3 Sum Closest / Smaller, 4 Sum
    • 对撞型,灌水类
    • 对撞型,partition类
    • Wiggle Sort I & II
    • 双指针,窗口类
    • 双指针,窗口类
    • Heap,排序 matrix 中的 two pointers
  • Bit & Math,位运算与数学
    • Bit Manipulation,对于 '1' 位的操作
    • Math & Bit Manipulation, Power of X
    • 坐标系 & 数值计算类
    • Add Digits
    • 用 int 做字符串 signature
  • Interval 与 扫描线
    • Range Addition & LCS
    • 7/5, Interval 类,扫描线
  • Trie,字典树
    • 6/9, Trie, 字典树
  • 单调栈,LIS
    • 4/13 LIS
    • 栈, 单调栈
    • Largest Divisible Subset
  • Binary Search 类
    • Matrix Binary Search
    • Array Binary Search
    • Find Peak Element I & II
    • **Median of Two Sorted Arrays
  • Graph & Topological Sort,图 & 拓扑排序
    • 有向 / 无向 图的基本性质和操作
    • 拓扑排序, DFS 做法
    • 拓扑排序, BFS 做法
    • Course Schedule I & II
    • Alien Dictionary
    • Undirected Graph, BFS
    • Undirected Graph, DFS
    • 矩阵,BFS 最短距离探索
    • 欧拉回路,Hierholzer算法
    • AI, 迷宫生成
    • AI, 迷宫寻路算法
    • (G) Deep Copy 无向图成有向图
  • 括号与数学表达式的计算
  • Iterator 类
  • Majority Element,Moore's Voting
  • Matrix Inplace Operations
  • 常见数据结构设计
  • (G) Design / OOD 类算法题
  • 随机算法 & 数据结构
  • (FB) I/O Buffer
  • (FB) Simplify Path, H-Index I & II
  • (FB) Excel Sheet, Remove Duplicates
  • Integer 的构造,操作,序列化
  • Frequency 类问题
  • Missing Number 类,元素交换,数组环形跳转
  • 8/10, Google Tag
  • (FB) Rearrange String k Distance Apart
  • Abstract Algebra
    • Chap1 -- Why Abstract Algebra ?
    • Chap2 -- Operations
    • Chap3 -- The Definition of Groups
Powered by GitBook
On this page
  • 这组问题的分类上基本延续了九章高级算法班的大纲,加了些听课时候的笔记,和自己之后查资料的思考。
  • 动态规划问题的种类更杂,一般来讲也更 tricky 一些。因为这类问题建立在对问题的状态空间和子问题结构有清晰的认识,并且能正确定义和缓存子问题结果上。即使最后的代码看起来可能只是几个循环,但是从复杂程度上大多数要高于暴力搜索和二叉树。
  • 见到题基本的判断,用 DP 做的题大多返回 boolean / int ,求 Max /Min ,而且不能打乱原输入顺序。
  • 动态规划有两个重要定义,一个叫 "optimal substructure",另一个叫 "overlap subproblem".
  • 根据CLRS,动态规划分为两种:
  • 动态规划的另一个要素是 "optimal substructure":

Was this helpful?

Dynamic Programming, 动态规划

这组问题的分类上基本延续了九章高级算法班的大纲,加了些听课时候的笔记,和自己之后查资料的思考。

动态规划问题的种类更杂,一般来讲也更 tricky 一些。因为这类问题建立在对问题的状态空间和子问题结构有清晰的认识,并且能正确定义和缓存子问题结果上。即使最后的代码看起来可能只是几个循环,但是从复杂程度上大多数要高于暴力搜索和二叉树。

见到题基本的判断,用 DP 做的题大多返回 boolean / int ,求 Max /Min ,而且不能打乱原输入顺序。

动态规划有两个重要定义,一个叫 "optimal substructure",另一个叫 "overlap subproblem".

各种排序 / Tree 类问题中,都会用到 divide & conquer 的思想,去把问题分成若干个 "disjoint" subproblems,然后递归解决。

"Disjoint" subproblem 在 Tree 类问题上体现的最为明显,左子树是左子树的问题,右子树是右子树的问题。因此 Tree 类问题上,更多的是解决“disjoint subproblem 的整合” 还有 “非连续 subproblem 的处理”。

而动态规划的中心思想是,面对 search tree 里都是 "overlap subproblem",如何根据问题结构制定缓存策略,避免重叠问题重复计算。

根据CLRS,动态规划分为两种:

  • top-down with memoization (递归记忆化搜索)

    • 等价于带缓存的,搜索树上的 DFS

    • 比较贴近于新问题正常的思考习惯

  • bottom-up (自底向上循环迭代)

    • 以 "reverse topological order" 处理

    • 每个子问题下面依赖的所有子问题都算完了才开始计算当前

    • 一般依赖于子问题之间天然的 "size" 联系

两种解法 big-O 时间复杂度一致,bottom-up 的 constant factor 小一些。

Rod-Cutting 的"subproblem graph"(子问题图),可以看到如果以 "subtree" 为单位定义 "subproblem" 的话,这个子问题图的结构有非常多的 "identical subtree" ,也即多个 "overlap subproblem". 这样结构的子问题图有 2^N 的节点和 2^(N-1) 个叶节点,不做任何记忆化搜索的话必然是指数级时间复杂度。

因此,动态规划的时间复杂度分析和子问题图 G = (V,E) 的结构息息相关。V = Vertex,代表每一个子问题; E = Edge,代表子问题之间结构。一般来讲,解决一个子问题的时间复杂度和其对应 V 的 out-degree 成正比;子问题的数量等于 V 的数量,既然每个子问题只被计算一次,在整个子问题图上做动态规划的复杂度,和 O(E + V) 成正比。

动态规划的另一个要素是 "optimal substructure":

  • A problem is said to have optimal substructure if an optimal solution can be constructed efficiently from optimal solutions of its subproblems.

  • optimal substructure 指,一个问题的最优解,可以由其子问题的最优解构造出来。

What is optimal/non-optimal substructure? A problem is said to have optimal substructure if an optimal solution can be constructed efficiently from optimal solutions of its subproblems. This property is used to determine the usefulness of dynamic programming and greedy algorithms for a problem What is local and global optimum? Local optimum of an optimization problem is a solution that is optimal (either maximal or minimal) within a neighboring set of candidate solutions. Global optimum - is the optimal solution among all possible solutions, not just those in a particular neighborhood of values. How to prove that Greedy algorithm yields global optimum? Usually, global optimum can be proven by induction. Typically, a greedy algorithm is used to solve a problem with optimal substructure if it can be proved by induction that this is optimal at each step. Otherwise, providing the problem exhibits overlapping subproblems as well, dynamic programming is used. To prove that an optimization problem can be solved using a greedy algorithm, we need to prove that the problem has the following:

  • Optimal substructure property: an optimal global solution contains the optimal solutions of all its subproblems.

  • Greedy choice property: a global optimal solution can be obtained by greedily selecting a locally optimal choise.

  • Matroids can be used as well in some case used to mechanically prove that a particular problem can be solved with a greedy approach.

You will find yourself following a common pattern in discovering optimal substructure:

  1. You show that a solution to the problem consists of making a choice, such as choosing an initial cut in a rod or choosing an index at which to split the matrix chain. Making this choice leaves one or more subproblems to be solved.

  2. You suppose that for a given problem, you are given the choice that leads to an optimal solution. You do not concern yourself yet with how to determine this choice. You just assume that it has been given to you.

  3. Given this choice, you determine which subproblems ensue and how to best characterize the resulting space of subproblems.

  4. You show that the solutions to the subproblems used within an optimal solution to the problem must themselves be optimal by using a “cut-and-paste” technique. You do so by supposing that each of the subproblem solutions is not optimal and then deriving a contradiction. In particular, by “cutting out” the nonoptimal solution to each subproblem and “pasting in” the optimal one, you show that you can get a better solution to the original problem, thus contradicting your supposition that you already had an optimal solution. If an optimal solution gives rise to more than one subproblem, they are typically so similar that you can modify the cut-and-paste argument for one to apply to the others with little effort.

PreviousUnion-Find, 并查集应用Next6/20, 入门 House Robber

Last updated 4 years ago

Was this helpful?