算法之分治算法

分治算法( divide and conquer )的核心思想其实就是四个字,分而治之 ,也就是将原问题划分成 n 个规模较小,并且结构与原问题相似的子问题,递归地解决这些
子问题,然后再合并其结果,就得到原问题的解。
这个定义看起来有点类似递归的定义。关于分治和递归的区别,我们在排序(下)的时候讲过,分治算法是一种处理问题的思想,递归是一种编程技巧。实际
上,分治算法一般都比较适合用递归来实现。分治算法的递归实现中,每一层递归都会涉及这样三个操作:
分解:将原问题分解成一系列子问题;
解决:递归地求解各个子问题,若子问题足够小,则直接求解;
合并:将子问题的结果合并成原问题。
分治算法能解决的问题,

一般需要满足下面这几个条件:

原问题与分解成的小问题具有相同的模式;
原问题分解成的子问题可以独立求解,子问题之间没有相关性,这一点是分治算法跟动态规划的明显区别,等我们讲到动态规划的时候,会详细对比这两种
算法;
具有分解终止条件,也就是说,当问题足够小时,可以直接求解;
可以将子问题合并成原问题,而这个合并操作的复杂度不能太高,否则就起不到减小算法总体复杂度的效果了。

分治算法可以求解的一些经典问题

1二分搜索 2大整数乘法 3 棋盘覆盖 4 合并排序 5 快速排序 6线性时间选择 7 最接近点对问题 8 循环赛日程表 9 汉诺塔

分治(Divide-and-Conquer§)算法设计模式如下

在这里插入图片描述

分治算法的基本步骤

  • 1 分治法在每一层递归上都有三个步骤:

  • 2 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题

  • 3 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题

  • 4 合并:将各个子问题的解合并为原问题的解。

在这里插入图片描述
使用分治算法解决汉诺塔问题

汉诺塔问题

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

分析:

A 如果是有一个盘, A->C

B 如果我们有 n >= 2 情况,我们总是可以看做是两个盘 1.最下边的盘 2. 上面的盘

  • 1 先把 最上面的盘 A->B

  • 2 把最下边的盘 A->C

  • 3 把B塔的所有盘 从 B->C

可以看出 汉诺塔问题可以拆分成以上AB两个大步,分解成的子问题可以独立求解,子问题之间没有相关性

如果有多个盘则分成AB 步骤,对AB步骤进行求解

设n个盘子的移动次数为T(n)

T(n)=2T(n-1)+1
T(1)=1
所以Hanoi塔算法的时间复杂度为O(2^n)

public class DivideAndConquer {

    public static void main(String[] args) {

        hanoiProblem(3, 'A', 'B', 'C');

    }


    /* 
     * @param: [discNum, discA, discB, discC] 
     * @return: void
     * @author: Jerssy
     * @dateTime: 2021/5/3 16:47
     * @description:
     */
    public static void   hanoiProblem(int discNum,char discA,char discB,char discC){

        if (discNum == 1) {

            System.out.println("the 1 disc move from "+discA+"-->"+discC);
        }
        else {

            hanoiProblem(discNum-1, discA, discC, discB);

            System.out.println("the "+discNum+" disc move from "+discA+"-->"+discC);

            hanoiProblem(discNum-1, discB, discA, discC);

        }

    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值