分治算法
1. 介绍
- 分治法就是“分而治之”,就是把一个复杂的问题分成两个或者更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单直接求解,原问题的子问题的解的合并就是原问题的解;
- 分而治之是一些高效算法的基础,如排序算法(快排,归并),傅里叶变换(快速傅里叶变换)…
- 分治算法可以求解一些经典的问题
- 二分搜索
- 大整数乘法
- 棋牌覆盖
- 合并排序
- 快速排序
- 线性时间选择
- 最接近点对问题
- 循环赛日程表
- 汉诺塔
2. 基本步骤
分治法在每一层递归上都有三个步骤:
1. 分解:将原问题分解为若干个小问题,相互独立,与原问题形式相同的子问题
2. 解决:若小问题规模较小而且容易被解决则直接解,否则递归地解决各个子问题
3. 合并:将各个子问题的解合并为原问题的解
3. 分治算法实践—汉诺塔
题目要求:
大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?
思路分析
- 如果只有一个盘,A->C
- 如果我们有n>=2个盘子,我们总是可以看作是两个盘子(最下面的一个盘子和上面所有的盘)
- 先把最上面的盘A->B
- 把最下面的盘A->C
- 把B塔的所有盘从B->C
代码实现
package Algorithm.DivideAndConquer;
public class HanoiTower {
public static void main(String[] args) {
hanoiTower(4,'A','B','C');
}
//汉诺塔移动方法
//使用分治算法解决
public static void hanoiTower(int num, char a, char b,char c){
//如果只有一个盘
if (num==1){
System.out.println("第1个盘从"+a+"->"+c);
}else {
/*如果我们有n>=2个盘子
我们总是可以看作是两个盘子
(最下面的一个盘子和上面所有的盘)*/
//1. 先把最上面的盘A->B,移动过程中用到了C
hanoiTower(num-1,a,c,b);
//2. 把最下面的盘A->C
System.out.println("第"+num + "个盘从"+a+"->"+c);
//3. 把B塔的所有的盘从B—>C,移动过程中用到了A
hanoiTower(num-1,b,a,c);
}
}
}