分治算法

一、分治思想

分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题可用二分法完成。

  • 解题步骤
    1. 分解:将要解决的问题划分成若干规模较小的同类问题;
    2. 求解:当子问题划分得足够小时,用较简单的方法解决;
    3. 合并:按原问题的要求,将子问题的解逐层合并构成原问题的解。
  • 经典问题:二分搜索、大整数乘法、棋盘覆盖、合并排序、快速排序、线性时间选择、最接近点对问题、循环赛日程表、汉诺塔

二、经典案例-汉诺塔

汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

2.1 算法思路

  • 步骤分析

    1. 如果是有一个盘,直接A->C;如果我们有盘数大于或等于2 的情况,我们总是可以看做是两个盘(分治) :①.最下边的盘;②.上面所有的盘。
    2. 先把最上面的盘 A->B(拆分);
    3. 把最下边的盘 A->C(求解);
    4. 把柱B的所有盘从 B->C(合并)。
  • 如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C。

  • 3阶汉诺塔移动过程-示意图

在这里插入图片描述

2.2 代码示例

需求:递归实现3阶汉诺塔的移动。

public class HanoiTower {

    public static void main(String[] args) {
        HanoiTower hanoi = new HanoiTower();
        // 3阶汉诺塔。
        hanoi.hanoi(3, 'A', 'B', 'C');
        // Direction:A--->C
        // Direction:A--->B
        // Direction:C--->B
        // Direction:A--->C
        // Direction:B--->A
        // Direction:B--->C
        // Direction:A--->C
    }

    /**
     * 使用分治算法,解决汉诺塔问题。
     *
     * @param n           盘子的数目
     * @param origin      源座
     * @param assist      辅助座
     * @param destination 目的座
     */
    public void hanoi(int n, char origin, char assist, char destination) {
        // 只有一个盘的时候,直接从 A->C 。
        if (1 == n) {
            move(origin, destination);
        } else {
            // 如果我们有 n>=2 情况,我们总是可以看做是两个盘(分治思想):1.最下边的一个盘 ; 2.上面的所有盘。
            // 1. 先把最上面的所有盘 A(当前源座)->B(当前目的座), 移动过程会使用到柱C(当前辅助座)。 
            hanoi((n - 1), origin, destination, assist);
            // 2. 把最下边的盘 A->C 。
            move(origin, destination);
            // 3. 把柱B的所有盘从 B(当前源座)->C(当前目的座) , 移动过程使用到柱A(当前辅助座)。
            hanoi(n - 1, assist, origin, destination);
        }
    }

    /**
     * 展示移动过程。
     *
     * @param origin      源座
     * @param destination 目的座
     */
    private void move(char origin, char destination) {
        System.out.println("Direction:" + origin + "--->" + destination);
    }
}

三、结束语


“-------怕什么真理无穷,进一寸有一寸的欢喜。”

微信公众号搜索:饺子泡牛奶

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值