概述

经典算法:

  • 二分查找
  • 快速排序、归并排序
  • KMP算法
  • 快慢指针(双指针)
  • 普利姆(Prim)、克鲁斯卡尔(Kruskal)算法
  • 迪克斯特拉(Dijkstra)
  • 优化算法:模拟退火、蚁群、遗传算法

复杂度

算法复杂度:大O表示法

空间复杂度:定义变量消耗空间,递归调用栈也需要计算

考虑最好情况、最坏情况、平均复杂度

分类

目的:搜索、排序、字符串、图、最优化、数学

方式:暴力、增量、分治、贪心、动态规划、回溯、分支限定

分治

大问题分小问题解决,再合并

递归可以很好的拆分合并

步骤:

  • 拆分独立子问题
  • 规模小时直接解,否则继续递归拆分
  • 将子问题合并

场景:

  • 二分搜索、大整数乘法、归并排序、快速排序
  • 棋盘覆盖、循环赛日程表、汉诺塔

贪心

总是做出当前最好的,做到局部最优,不考虑整体最优

场景:

  • 哈夫曼编码(根据字符出现的频率,用0/1表示)
  • 直接求解全局最优(需要无后效性)

动态规划

过程:

  • 原问题分成多个阶段,依次决策,得到局部解
  • 每次决策依赖当前状态、才发生状态转移

场景:

  • 最优二叉树搜索树、最长公共子序列、背包问题

回溯

  • 一条路上发现不对就回到以前的步骤重新选择
  • 通过解题

DFS深度优先搜索,树、图,其实就是回溯

分支限定

BFS广度优先搜索

  • 每一层所有节点都记录,抛弃不符合条件的节点

  • 每个节点作为下一个扩展节点继续搜索

数组问题

两数之和、三数之和(为零)、旋转图像(22/8/11)

旋转图像中,

  1. 通过观察可得,矩阵转置再沿着中间对称即可得到旋转后的图像
  2. 分治法中,将图像划分四个区域(除去不需要移动的),观察可得,(y,x)会移动到(n -x -1,y),以此为规律,依次移动4个区域即可