概念
分而治之,大问题分解成为n个同样解决步骤的相同问题,小问题的解可以合并成大问题的解。这么一看,满足分治思想的问题都是满足递归条件的——可分解,有结束条件,所以下边的几个算法基本全是递归。
常见问题
二分查找
在一大堆数中找某(些)数,使用条件:给的数据得是排好序的
coding
问题描述:一个有序列表,返回值为 ‘hohoho’ 的元素下标。
1 | const list = ['ahhh','baaa','cola','diii','emmm','hohoho','icu','jack Ma','kuuu','mumumu'] |
1 | import math |
思路
从中间开始比较,每次比较都可以丢弃一半无用数据。
二分法有三个指针(low,high,mid),通过比较改变low,high的值缩小查找范围,最终让mid命中target。可以看到,while里的部分就是分解出的小问题的解决步骤。通过不断的解决小问题,获得源问题的解。
归并排序
嗯,就是排序
coding
1 | function merge_sort (list) { |
1 | import math |
思路
分治思想嘛,先分后治,引用一个图。
“分”的阶段将数组层层分解,最终分解为单个元素。
“治”的阶段由单个元素开始,层层排序,最终合并成一个完整的有序数组。
快速排序
嗯,也是排序
coding
1 | function quick_sort (list) { |
1 | import math |
思路
选择数组中间的一个元素为基准,大于这个基准的移到右边,小于基准的移到左边,左 + 中 + 右构成了一个新数组,对左右数组递归重复以上过程,最终就得到了排好序的数组。
总结
分治法类似数学归纳法,但是和做数学题有点不一样。大致步骤为
- 找出分解问题的方法
- 将源问题分解成多个小问题
- 找出小问题的求解公式
- 考虑随着问题规模增大时的求解方法
- 设计递归函数