算法之分治算法

本文深入探讨了分治算法的核心思想,包括分解、解决和合并三个步骤,并通过汉诺塔问题举例说明了分治策略的运用。汉诺塔问题的递归解决方案展示了分治算法如何将大问题拆解为独立子问题并最终合并结果。此外,文章还阐述了分治算法适用问题的条件,并列举了其他经典应用场景如二分搜索、快速排序等。
摘要由CSDN通过智能技术生成

分治算法( 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);

        }

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值