Coursera - Algorithm (Stanford) - 课程笔记 - Week 2

本文深入探讨了分治算法的基本原理及其在计数逆序对、Strassen矩阵乘法及最近点对问题中的应用。通过将问题分解为子问题,递归解决并合并结果,分治算法能有效降低复杂度,如O(nlogn)的逆序对算法和次立方级别的Strassen矩阵乘法。文章还介绍了主定理,用于分析分治算法的时间复杂度。

Divide & Conquer Algorithms

O(n log n) Algorithm for Counting Inversions

  • 分治算法
    • 将问题分割为更小的子问题
    • 通过递归调用解决这些问题
    • 将子问题的结果合并到更大的子问题中作为其结果
  • 逆序对
    • 数组中存在的i < j但是a[i] > a[j]的情况
    • 左逆序对:二者都在左半部分
    • 右逆序对:二者都在右半部分
    • 跨逆序对:分别在两侧
  • 思路:将归并排序融合进来
    • 两个半部分一边数逆序对一边排序,对两个有序的半部分再归并同时计算逆序对
  • 归并时,对于右侧的一个数字y,若复制到目标数组时,其相关的逆序对个数即此时左侧剩下的元素个数
  • 因为整个过程基于归并排序,因此与归并排序有着相同的时间复杂度(O(nlog⁡n)O(n \log n)O(nlogn)

Strassen’s Subcubic Matrix Multiplication

  • 直接计算矩阵:立方级别时间复杂度
  • 递归算法:
    • 将矩阵等分成四个部分
    • 将两个矩阵的乘积转化为八个小矩阵的乘积(八个递归项)
    • 做加和处理
    • 仍旧是立方复杂度
  • Steassen算法
    • 递归项只有7个
    • 进行必要的加和和相减处理
    • 八个小矩阵为A~H
    • 递归计算七个积:
      • P1=A(F−H)P_1=A(F-H)P1=A(FH)
      • P2=(A+B)HP_2=(A+B)HP2=(A+B)H
      • P3=(C+D)EP_3=(C+D)EP3=(C+D)E
      • P4=D(G−E)P_4=D(G-E)P4=D(GE)
      • P5=(A+D)(E+H)P_5=(A+D)(E+H)P5=(A+D)(E+H)
      • P6=(B−D)(G+H)P_6=(B-D)(G+H)P6=(BD)(G+H)
      • P7=(A−C)(E+F)P_7=(A-C)(E+F)P7=(AC)(E+F)
    • X+Y=(AE+BGAF+BHCE+DGCF+DH)=(P5+P4−P2+P6P1+P2P3+P4P1+P5−P3−P7)X+Y = (\begin{matrix}AE+BG & AF+BH \\ CE+DG & CF+DH\end{matrix}) = (\begin{matrix} P_5+P_4-P_2+P_6 & P_1+P_2 \\ P_3+P_4 & P_1+P_5-P_3-P_7 \end{matrix})X+Y=(AE+BGCE+DGAF+BHCF+DH)=(P5+P4P2+P6P3+P4P1+P2P1+P5P3P7)
    • 有效地降低了复杂度(次立方级别复杂度)

Closet Pair

  • 最近点对问题:
    • 给出一组平面上的点
    • 找出其中距离最近的一对
    • 距离为点的欧氏距离
    • 假设所有点坐标不同(相同亦可)
  • 暴力搜索:θ(n2)\theta(n^2)θ(n2)的时间复杂度
  • 1-D平面上的点:归并排序后遍历相邻点的距离(O(nlog⁡n)O(n \log n)O(nlogn)
  • 基本思路:类似逆序对算法,进行归并式的寻找,时间复杂度同样为(O(nlog⁡n)O(n \log n)O(nlogn)
  • 关键思路:只计算尚未“解锁”的情形中距离比现有递归结果最小的部分
  • 计算过程
    • 将点按照坐标的从大到小排序,将Q和R表示为点集的左半部分和右半部分
    • 计算(p1,q1)为Q中最近对
    • 计算(p2,q2)为P中最近对
    • 计算两个对的最小者的距离δ
    • 根据δ和P,计算跨两部分的最近对(p3,q3)
    • 取三者最小向上递归结果
  • split最近对的寻找:线性时间扫描
    • 一次只看7个点(已经按照y坐标排序)

The Master Method

  • 对分治算法的数学分析:循环表示法(Recurrence)
  • 循环表示法的形式化表示(假设子问题的大小均一致):
    • 基本情形:对足够小的nnnT(n)≤a constantT(n) \le \text{a constant}T(n)a constant
    • 对其他更大的nnnT(n)≤aT(nb)+O(nd)T(n) \le aT(\frac nb) + O(n^d)T(n)aT(bn)+O(nd)
      • a:递归调用的个数
      • b:输入大小的缩减因子
      • d:对递归调用结果的加和操作的指数因子
    • 如果a=bda=b^da=bdT(n)=(ndlog⁡n)T(n)=(n^d \log n)T(n)=(ndlogn)
    • 如果a<bda < b^da<bdT(n)=(nd)T(n)=(n^d)T(n)=(nd)
    • 如果a>bda > b^da>bdT(n)=(nlog⁡ba)T(n)=(n^{\log_b a})T(n)=(nlogba)
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值