分治算法
思想
当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。
分治法解题步骤
(1)分解,将要解决的问题划分成若干规模较小的同类问题;
(2)求解,当子问题划分得足够小时,用较简单的方法解决;
(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。
分治算法经典——汉诺塔
汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
汉诺塔Java实现
package dac;
public class HanoiTower {
public static void main(String[] args) {
//分治算法的汉诺塔问题
hanoiTower(5,'A','B','C');
}
/**
* @param num 一共有多少个盘
* @param a a塔
* @param b b塔
* @param c c塔
*/
public static void hanoiTower(int num, char a, char b, char c) {
//如果只有一个盘,从a移动到c
if (num == 1) {
System.out.println("第1个盘从 " + a + "——>" + c);
} else {
//如果有n>=2个盘,应该看成只有两个盘,将最下面的一个盘和上面的所有盘分开看待。
//先把最上面的所有盘a——>b,移动过程会使用到c
hanoiTower(num - 1, a, c, b);
//把最下面的盘从a——>c
System.out.println("第" + num + "个盘从 " + a + "——>" + c);
//把B塔的所有盘从b——>c,移动过程会使用到a塔
hanoiTower(num-1, b, a, c);
}
}
}
运行结果
第1个盘从 A——>C
第2个盘从 A——>B
第1个盘从 C——>B
第3个盘从 A——>C
第1个盘从 B——>A
第2个盘从 B——>C
第1个盘从 A——>C
第4个盘从 A——>B
第1个盘从 C——>B
第2个盘从 C——>A
第1个盘从 B——>A
第3个盘从 C——>B
第1个盘从 A——>C
第2个盘从 A——>B
第1个盘从 C——>B
第5个盘从 A——>C
第1个盘从 B——>A
第2个盘从 B——>C
第1个盘从 A——>C
第3个盘从 B——>A
第1个盘从 C——>B
第2个盘从 C——>A
第1个盘从 B——>A
第4个盘从 B——>C
第1个盘从 A——>C
第2个盘从 A——>B
第1个盘从 C——>B
第3个盘从 A——>C
第1个盘从 B——>A
第2个盘从 B——>C
第1个盘从 A——>C
Process finished with exit code 0