数据结构与算法-分治法

简介: 分治法:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后让他们彼此异化。

分治法:


把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后让他们彼此异化。


设计思想:


将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。


策略:


对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。


精髓:


分--将问题分解为规模更小的子问题;


治--将这些规模更小的子问题逐个击破;


合--将已解决的子问题合并,最终得出“母”问题的解;


特征:


1) 该问题的规模缩小到一定的程度就可以容易地解决


2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。


3) 利用该问题分解出的子问题的解可以合并为该问题的解;


4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。


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


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


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


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


分治法(递归技术)


直接或间接调用自身的算法。


注意:因为递归可以替代循环,故必须有终止。否则慎用。


for (int i = 0; i <= 10; i++) {
    Log.e("SCCDemo", "Pos" + i + "返回:" + d(i));
}
//2021/5/26 功能描述:分治法(递归技术)
private int d(int pos) {
    if (pos == 0 || pos == 1) {
        return 1;
    } else {
        return d(pos - 1) + d(pos - 2);
    }
}

输出:


E/SCCDemo: Pos0返回:1===========E/SCCDemo: Pos1返回:1、


E/SCCDemo: Pos2返回:2===========E/SCCDemo: Pos3返回:3


E/SCCDemo: Pos4返回:5===========E/SCCDemo: Pos5返回:8


E/SCCDemo: Pos6返回:13==========E/SCCDemo: Pos7返回:21


E/SCCDemo: Pos8返回:34==========E/SCCDemo: Pos9返回:55



分治法(二分查找法)


二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。


要求:


1) 必须采用顺序存储结构。


2) 必须按关键字大小有序排列。


ArrayList<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 29; i++) {
    numbers.add(i);
}


/**
 * 功能描述:分治法(二分查找)
 * @param numbers   数组
 * @param a         起点
 * @param b         终点
 * @param lookUpNum 查找的数
 */
private void e(ArrayList<Integer> numbers, int a, int b, int lookUpNum) {
    if (a > b) {//查找完且未找到结果,查找失败
        Log.e("SCCDemo", "lookUpNum:" + lookUpNum + "返回:-1");
    } else {
        int mid = (a+b)/2;//找到中间点,可能导致溢出,应该使用mid=(b-a)/2+a;
        Log.e("SCCDemo", "mid:" + numbers.get(mid));
        if (numbers.get(mid) == lookUpNum) {
            Log.e("SCCDemo", "lookUpNum:" + lookUpNum + "返回:" + mid);
        } else {
            if (numbers.get(mid) > lookUpNum) {
                Log.e("SCCDemo", "查找范围:(" + a + "," + (mid - 1) + ")");
                //中间值大于lookUpNum,查找范围锁定是(a,(mid-1));
                e(numbers, a, mid - 1, lookUpNum);
            } else {
                Log.e("SCCDemo", "查找范围:(" + (mid + 1) + "," + b + ")");
                //中间值小于lookUpNum,查找范围锁定是((mid+1),b);
                e(numbers, mid + 1, b, lookUpNum);
            }
        }
    }
}


e(numbers, 0, numbers.get(numbers.size()-1), 1);


E/SCCDemo: mid:14——比较后——E/SCCDemo: 查找范围:(0,13)


E/SCCDemo: mid:6——比较后——E/SCCDemo: 查找范围:(0,5)


E/SCCDemo: mid:2——比较后——E/SCCDemo: 查找范围:(0,1)


E/SCCDemo: mid:0——比较后——E/SCCDemo: 查找范围:(1,1)


E/SCCDemo: mid:1——比较后——E/SCCDemo: lookUpNum:1返回:1


e(numbers, 0, numbers.get(numbers.size()-1), 15);


E/SCCDemo: mid:14——比较后——E/SCCDemo: 查找范围:(15,28)


E/SCCDemo: mid:21——比较后——E/SCCDemo: 查找范围:(15,20)


E/SCCDemo: mid:17——比较后——E/SCCDemo: 查找范围:(15,16)


E/SCCDemo: mid:15——比较后——E/SCCDemo: lookUpNum:15返回:15


e(numbers, 0, numbers.get(numbers.size()-1), 28);


E/SCCDemo: mid:14——比较后——E/SCCDemo: 查找范围:(15,28)


E/SCCDemo: mid:21——比较后——E/SCCDemo: 查找范围:(22,28)


E/SCCDemo: mid:25——比较后——E/SCCDemo: 查找范围:(26,28)


E/SCCDemo: mid:27——比较后——E/SCCDemo: 查找范围:(28,28)


E/SCCDemo: mid:28——比较后——E/SCCDemo: lookUpNum:28返回:28


相关文章
|
5月前
|
算法 开发者 Python
惊呆了!Python算法设计与分析,分治法、贪心、动态规划...这些你都会了吗?不会?那还不快来学!
【7月更文挑战第10天】探索编程巅峰,算法至关重要。Python以其易读性成为学习算法的首选。分治法,如归并排序,将大问题拆解;贪心算法,如找零问题,每步求局部最优;动态规划,如斐波那契数列,利用子问题解。通过示例代码,理解并掌握这些算法,提升编程技能,面对挑战更加从容。动手实践,体验算法的神奇力量吧!
75 8
|
5月前
|
算法 Python
算法不再难!Python分治法、贪心、动态规划实战解析,轻松应对各种算法挑战!
【7月更文挑战第8天】掌握Python算法三剑客:分治、贪心、动态规划。分治如归并排序,将大问题拆解递归解决;贪心策略在每步选最优解,如高效找零;动态规划利用子问题解,避免重复计算,解决最长公共子序列问题。实例展示,助你轻松驾驭算法!**
72 3
|
1月前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
46 2
|
4月前
|
算法 搜索推荐
算法设计 (分治法应用实验报告)基于分治法的合并排序、快速排序、最近对问题
这篇文章是关于分治法应用的实验报告,详细介绍了如何利用分治法实现合并排序和快速排序算法,并探讨了使用分治法解决二维平面上的最近对问题的方法,包括伪代码、源代码实现及时间效率分析,并附有运行结果和小结。
|
5月前
|
算法 Python
Python算法高手进阶指南:分治法、贪心算法、动态规划,掌握它们,算法难题迎刃而解!
【7月更文挑战第10天】探索Python算法的精华:分治法(如归并排序)、贪心策略(如找零钱问题)和动态规划(解复杂问题)。通过示例代码揭示它们如何优化问题解决,提升编程技能。掌握这些策略,攀登技术巅峰。
139 2
|
5月前
|
算法 程序员 Python
算法小白到大神的蜕变之路:Python分治法、贪心、动态规划,一步步带你走向算法巅峰!
【7月更文挑战第9天】探索算法之旅,以Python解锁编程高手之路。分治法如二分查找,将复杂问题拆解;贪心算法解决活动选择,每次选取局部最优;动态规划求斐波那契数列,避免重复计算,实现全局最优。每一步学习,都是编程能力的升华,助你应对复杂挑战,迈向算法大师!
49 1
|
5月前
|
存储 算法 Python
Python算法界的秘密武器:分治法巧解难题,贪心算法快速决策,动态规划优化未来!
【7月更文挑战第9天】Python中的分治、贪心和动态规划是三大关键算法。分治法将大问题分解为小问题求解,如归并排序;贪心算法每步选局部最优解,不保证全局最优,如找零钱;动态规划存储子问题解求全局最优,如斐波那契数列。选择合适算法能提升编程效率。
71 1
|
5月前
|
存储 算法 Python
震撼!Python算法设计与分析,分治法、贪心、动态规划...这些经典算法如何改变你的编程世界!
【7月更文挑战第9天】在Python的算法天地,分治、贪心、动态规划三巨头揭示了解题的智慧。分治如归并排序,将大问题拆解为小部分解决;贪心算法以局部最优求全局,如Prim的最小生成树;动态规划通过存储子问题解避免重复计算,如斐波那契数列。掌握这些,将重塑你的编程思维,点亮技术之路。
79 1
|
5月前
|
存储 算法 大数据
Python算法高手的必修课:深入理解分治法、贪心算法、动态规划,让你的代码更智能!
【7月更文挑战第9天】在Python算法学习中,分治法(如归并排序)将大问题分解为小部分递归解决;贪心算法(如货币找零)在每步选择局部最优解尝试达到全局最优;动态规划(如斐波那契数列)通过存储子问题解避免重复计算,解决重叠子问题。掌握这三种方法能提升代码效率,解决复杂问题。
55 1
|
5月前
|
算法 索引 Python
逆袭算法界!Python分治法、贪心算法、动态规划深度剖析,带你走出算法迷宫!
【7月更文挑战第8天】分治法,如快速排序,将大问题分解并合并解;贪心算法,选择局部最优解,如活动选择;动态规划,利用最优子结构避免重复计算,如斐波那契数列。Python示例展示这些算法如何解决实际问题,助你精通算法,勇闯迷宫。
50 1