就像贪心算法和动态编程一样,分治算法也是一种算法范例。典型的分治算法分为三个步骤:
- 分解:将给定问题分解成类型相同的子问题
- 处理:递归处理每个子问题
- 合并:将子问题的解合并
1)二叉查找算法。每一步,算法比较给定的x值和数组中间位置元素,如果相等则返回数组索引。否则,如果x小于中间元素,则在数组左边递归查找;如果x大于中间元素,则在数组右边递归查找。
2)快速排序。这种排序算法是利用数组中的一个元素作为轴(pivot),根据数组元素值大小,将小值元素放到轴的左边,将大值元素放到轴的右边。用同样的规则递归处理左边元素和右边元素。
3)归并排序。算法将数组分为两部分,递归处理这两部分数组,然后合并。
4)最近点对。在x-y坐标系中找出最近的两个点。这个问题用暴力破解找出各点之间距离然后找出最小者,不过时间复杂度O(n^2)。用分治算法就可以将复杂度降到O(nlogn)。
5)Strassen算法是两个矩阵相乘的高效算法。用最简单的算法解决矩阵相乘需要时间复杂度O(n^3)。而Strassen算法的复杂度是O(n^2.8974) 。
6)Cooley-Tukey快速傅里叶变换算法是最常用的傅里叶变换算法。它用分治算法,使时间复杂度为O(nlogn)。
分治算法(D&c)vs 动态编程(DP)
这两种编程范例都是将问题划分成子问题,让后求解子问题。解题时候如何选择呢?当子问题不会被求解多次的时候就应该用分治算法,相反则使用动态编程。例如二叉查找算法就是用的分治算法,因为子问题没有被重复求解。而求斐波那契序列就需要动态编程了。