精华内容
下载资源
问答
  • 分治法基本思想

    千次阅读 2019-09-10 18:18:17
    分治法基本思想是将一个规模为n的问题分解为k个规模为m的相互独立且与原问题解法相同的子问题,然后将子问题的解合并得到原问题的解。 由此可见,分治法设计出的程序一般是递归算法,设解决一个规模为1的问题需要...

    分治法得基本思想是将一个规模为n的问题分解为k个规模为m的相互独立且与原问题解法相同的子问题,然后将子问题的解合并得到原问题的解。

    由此可见,分治法设计出的程序一般是递归算法,设解决一个规模为1的问题需要1个单位时间,再设将k个子问题的解合并为原问题的解所需时间为f(n),则递归算法的时间复杂度为:

                                                     

    解递归方程:

    ,

    主定理:

    • 时,T(n)=O();
    • 时,T(n)=O;(此处logn底数为2)
    • 时,T(n)=O(f(n));
    展开全文
  • 文章目录前言基本思想适用的问题求解步骤分治法要点时间复杂性分析举例-汉罗塔问题(Tower of Hanoi)问题描述解决步骤java代码 前言 分治法来源于孙子兵法谋攻篇中写道——十则围之,五则攻之,倍则战之,敌则能...

    前言

    分治法来源于孙子兵法谋攻篇中写道——十则围之,五则攻之,倍则战之,敌则能分支。讲述的是敌军对战时用兵的原则,如果有十倍的兵力围殴他,五倍的兵力仅供他,在兵力相当的情况下,应该考虑分而治之,各个击破,其体现出来的思想,称为分治法

    基本思想

    那么分治法的基本思想是什么呢?将一个难以直接解决的大问题,分割成一些规模较小的相同的问题,以便各个击破,分而治之。 通俗的来说就是大事化小,小事化了。大事不好解决,那么我们就把它分成若干个小事,小到什么程度呢?非常容易解决的时候。

    适用的问题

    1、该问题可以分解为若干个规模较小的相同问题。
    2、该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
    3、该问题的规模缩小到一定的程度的时候容易解决。
    4、利用该问题分解出的子问题的解可以合并俄日该问题的解。

    求解步骤

    1、分解: 把原问题分解为若干个规模较小,相互独立,与原问题相同的子问题
    2、求解:若子问题规模较小且容易被解决则直接解,否则在继续分解为更小的问题,知道容易解决。
    3、合并:将已经求解的各个子问题的解,逐步合并为原问题的解。

    分治法要点

    1、分几个?子问题规模多大?
    2、子问题如何求解?
    3、合并原问题的解?
    4、分析时间复杂性
    最好使子问题的规模大致相同。即将一个问题分成大小相等的k个子问题的处理方法是行之有效的。

    时间复杂性分析

    从分支法的代码中可以看出,分治法解决问题P(n)时,边界条件为n-0=1,此时问题的规模足够小,求解P(1)的时间耗费为O(1),在一般的情况下,将规模为n的大问题,分解为k个规模为n/m的子问题进行求解。将P(n)分解以及合并成原问题的时间为f(n)。中间for循环k次,解决每个子问题的时间复杂性为T(n/m),那么解决k个子问题所需要的时间为kT(n/m)
    在这里插入图片描述
    分治法解规模为n的问题最坏时间复杂性函数T(n)满足:
    在这里插入图片描述

    举例-汉罗塔问题(Tower of Hanoi)

    问题描述

    传说在婆罗门庙里有三座钻石宝塔塔台A,B和C,在A上有n=64个金盘,每一个都比下面的略小一点。那么如何通过柱子b将所有盘子挪到柱子C上?
    在这里插入图片描述
    移动要求
    1、一次只能移动一个金盘。
    2、移动过程中大金盘不能放在小金盘上面。

    解决步骤

    第一步:将(n-1)个盘子从A搬到B(借助C)
    在这里插入图片描述
    第二步:将A宝塔中,最低端的大盘子从A搬到C
    在这里插入图片描述
    第三步将B上的(n-1)盘子,借助A移动到C
    在这里插入图片描述
    边界条件n=1的时候,将这一个盘子直接从A移动到C,一次移动时间记为1,否则的话执行以下三部:
    1、用C做过渡,将A上的(n-1)个盘子移动到B上。
    2、将A上最后一个盘子直接移动到C上。
    3、用A柱做过渡,将B柱上的(n-1)个盘子移到C上。

    java代码

    package com.Xiang;
    
    public class Hanoi {
    
        public static void main(String[] args) {
                hanoiTower(4, 'A', 'B', 'C');
        }
        
        //汉诺塔的移动的方法
        //使用分治算法
        
        public static void hanoiTower(int num, char a, char b, char c) {
                //如果只有一个盘
                if(num == 1) {
                        System.out.println("第1个盘从 " + a + "->" + c);
                } else {
                        //如果我们有 n >= 2 情况,我们总是可以看做是两个盘 1.最下边的一个盘 2. 上面的所有盘
                        //1. 先把 最上面的所有盘 A->B, 移动过程会使用到 c
                        hanoiTower(num - 1, a, c, b);
                        //2. 把最下边的盘 A->C
                        System.out.println("第" + num + "个盘从 " + a + "->" + c);
                        //3. 把B塔的所有盘 从 B->C , 移动过程使用到 a塔  
                        hanoiTower(num - 1, b, a, c);
                        
                }
        }
    
    }
    /*
     * 第1个盘从 A->B
    第2个盘从 A->C
    第1个盘从 B->C
    第3个盘从 A->B
    第1个盘从 C->A
    第2个盘从 C->B
    第1个盘从 A->B
    第4个盘从 A->C
    第1个盘从 B->C
    第2个盘从 B->A
    第1个盘从 C->A
    第3个盘从 B->C
    第1个盘从 A->B
    第2个盘从 A->C
    第1个盘从 B->C
    
     */
    
    
    展开全文
  • 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个...
  • 分治法基本思想与例子解析

    万次阅读 2016-06-24 21:56:38
    分治法的设计思想:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。  凡治众如治寡,分数是也。——孙子兵法 1. 基本思想 (1) 将求解的较大规模的问题分割成k个更小规模的...
        分治法的设计思想:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

        凡治众如治寡,分数是也。——孙子兵法


    1.基本思想

    (1) 将求解的较大规模的问题分割成k个更小规模的子问题。


    (2) 对这k个子问题分别求解。如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。


    (3) 将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。

     

     

    2.适用条件

    分治法所能解决的问题一般具有以下几个特征:

    I. 该问题的规模缩小到一定的程度就可以容易地解决;
    II. 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质
    III. 利用该问题分解出的子问题的解可以合并为该问题的解;
    IV. 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。 


    注意:

           如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然也可用分治法,但一般用动态规划较好。


    3. 分治法的应用例子

    (a) 快速排序

    I. 分解(divide):以a[p]为基准元素将a[p:r]划分为3段a[p:q-1],a[q]和a[q+1,r],使得a[p:q-1]中任何元素小于等于a[q],a[q+1,r]中任何元素大于等于a[q]。下标q在划分过程中确定。

    II. 递归求解(conquer):通过递归调用快速排序算法,分别对a[p:q-1]和a[q+1,r]进行排序。

    III. 合并(merge):由于对a[p:q-1]和a[q+1,r]的排序时就地进行的,所以在a[p:q-1]和a[q+1,r]都已排好的序后不需要执行任何计算,a[p:r]就已排好序。

    package Sort;
    /**
     * @author LIn
     * 算法名称:快速排序
     * 算法描述:
     * 1.通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小
     * 2.重复步骤1对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
     *
     * 复杂度分析:
     * 1.平均时间复杂度:O(nlogn)
     * 2.空间复杂度:O(logn)(最值元素存储空间)
     */
    public class QuickSort {
    	
    	public static void quickSort(int[] a){
    		quickSort(a, 0, a.length - 1);
    	}
    
    	private static void quickSort(int[] a, int left, int right){
    		int pivotpos;  //划分后基准的位置
    		if(left < right){
    			pivotpos = Partition(a, left ,right);
    			quickSort(a, left, pivotpos-1);
    			quickSort(a, pivotpos+1, right);
    		}
    	}
    	
    	/**
    	 * 普通选择基准
    	 */
    	private static int Partition(int[] a, int p, int r){
    		//调用Partition(a,left,right)时,对a[left...right]做划分
    		//并返回基准记录的位置
    		int i = p, j = r + 1;
    		int pivot = a[p];  //用区间的第一个记录作为基准
    		
    		while(true){
    			while(a[++i] < pivot){}
    			while(a[--j] > pivot){}
    			if(i < j){
    				swap(a, i, j);
    			}
    			else{
    				break;
    			}
    		}
    		
    		swap(a, j, p);
    		return j;
    	}
    	
    	private static void swap(int[] a, int x, int y){
    		int temp = a[x];
    		a[x] = a[y];
    		a[y] = temp;
    	}
    
    }
    

    (b) 二分查找

           合并排序算法是用分治策略实现对n个元素进行排序的算法。其基本思想是:将待排序元素分成大小大致相同的2个子集合,分别对2个子集合进行排序,最终将排好序的子集合合并为所要求的排好序的集合。

    package Sort;
    /**
     * @author LIn
     * 算法名称:归并排序
     * 算法描述:
     * 1.将数组分为n等份(算法中为2),对各子数组递归调用归并排序
     * 2.等分为2份时为2路归并,最后子数组排序结束后,将元素合并起来,复制回原数组
     * 
     * 复杂度分析:
     * 1.平均时间复杂度:O(nlogn)
     * 2.空间复杂度:O(n)(临时数据储存空间)
     */
    public class MergeSort {
    	
    	/*public型的mergeSort是private型递归方法mergeSort的驱动程序*/
    	public static void mergeSort(int[] a){
    		int[] tempArray = new int[a.length];   //若数组元素为对象类型,需创建Comparable类的数组,再强转为该对象类型
    		
    		mergeSort(a, tempArray, 0, a.length - 1);
    	}
    	
    	/**
    	 * 递归调用归并排序
    	 */
    	private static void mergeSort(int[] a, int[] tempArray, int left, int right){
    		if(left < right){
    			int center = (left + right) / 2;
    			mergeSort(a, tempArray, left, center);
    			mergeSort(a, tempArray, center + 1, right);
    			merge(a, tempArray, left, center + 1, right);   //子数组排序结束后,将子数组合并
    		}
    	}
    	
    	/**
    	 * 合并左右的半分子数组
    	 * @param a          需排序数组
    	 * @param tempArray  临时存储数组
    	 * @param leftPos    左半子数组开始的下标
    	 * @param rightPos   右半子数组开始的下标
    	 * @param rightEnd   右半子数组结束的下标
    	 */
    	private static void merge(int[] a, int[] tempArray, int leftPos, int rightPos, int rightEnd) {
    		int leftEnd = rightPos - 1;
    		int tempPos = leftPos;
    		int num = rightEnd - leftPos + 1;
    		
    		//主循环
    		while(leftPos <= leftEnd && rightPos <= rightEnd){
    			if(a[leftPos] <= a[rightPos]){
    				tempArray[tempPos++] = a[leftPos++];
    			}else{
    				tempArray[tempPos++] = a[rightPos++];
    			}
    		}
    		/*比较结束后,只会有一个子数组元素未完全被合并*/
    		while(leftPos <= leftEnd){        //复制左半子数组剩余的元素
    			tempArray[tempPos++]  = a[leftPos++];
    		}
    		while(rightPos <= rightEnd){      //复制右半子数组剩余的元素
    			tempArray[tempPos++]  = a[rightPos++];
    		}
    		
    		//将元素从临时数组赋值回原数组
    		for(int i = 0; i < num; i++, rightEnd--){
    			a[rightEnd] = tempArray[rightEnd];
    		}
    		
    	}
    
    }
    

    参考资料:

    1. 《算法设计与分析》

    2. 《算法》


    展开全文
  • 分治法——基本思想

    千次阅读 2016-07-14 14:13:03
    分治法——基本思想设计过程 划分问题:整个问题划分成多个无关联的子问题 递归求解:求解各个子问题 递归调用正设计的算法 合并问题:合并子问题的解,形成原始问题的解 分析过程 建立递归方程 求解递归方程 递归...

    分治法——基本思想

    设计过程

    • 划分问题:整个问题划分成多个无关联的子问题
    • 递归求解:求解各个子问题
      • 递归调用正设计的算法
    • 合并问题:合并子问题的解,形成原始问题的解

    分析过程

    • 建立递归方程
    • 求解递归方程

    递归方程的建立方法

    • 设输入大小为 n T(n)为时间复杂性
    • n<c T(n)=θ(1)
    • 划分阶段的时间复杂性
      • 划分问题为a个子问题。
      • 每个子问题大小为 nb
      • 划分时间可直接得到= D(n)
    • 递归求解阶段的时间复杂度。
      • 递归调用
      • 求解时间= aT(nb)
    • 合并阶段的时间复杂性
      • 时间可以直接得到= C(n)

    结论

    T(n)={θ(1),aT(nb)+D(n)+C(n),if n<cif nc

    求解方式

    使用分治算法主定理,参考分治算法主定理

    展开全文
  • 分治法基本步骤

    千次阅读 2019-07-26 00:31:03
    分治法基本步骤 分治法在每一层递归上都有三个步骤: 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题; 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题;...
  • 分治法的核心思想是“分而治之”,当你需要采用分治法时,一般原问题都需要具备以下几个特征: 难度在降低,即原问题的解决难度,随着数据的规模的缩小而降低。这个特征绝大多数问题都是满足的。 问题可分,...
  • 分治法字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多...
  • 分治法基本知识

    2020-03-28 19:16:54
    一、分治法的设计思想 将一个难以直接求解的大问题,分解成若干个规模较小的子问题,递归地求解这些子问题,然后合并子问题的解得到原问题的解。 注意: 1.子问题与原问题形式相同 2.子问题可以彼此独立的求解,即...
  • 将两个及其以上的有序表合并为一张有序表,把待排序序列通过分治法分为若干个有序子序列,然后每两个子序列合并为一个子序列,经过多次合并后整合为一张有序表。 排序过程如图: 代码如下: #include stdio.h #...
  • 分治策略的基本思想

    千次阅读 2019-10-22 13:27:20
    分治策略的基本思想 分治策略( Divide and Conquer ) 1、将原始问题划分或者归结为规模较小的子问题 2、递归或迭代求解每个子问题(独立求解) 3、将子问题的解综合得到原问题的解 注意: 1.子问题与原始问题性质完全...
  • 大数据处理基本思想——分治法

    千次阅读 2019-03-11 23:45:29
    分治法的主要思想就是将一个复杂的问题分成两个或多个相同的子问题,子问题可以分成更小的子问题,直到子问题可以容易解决的时候,原问题的解就是子问题解的和。 下面我们举一个例子,我们先...
  • 打官腔:分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。 (图片源自百度) 上伪代码: type divede-...
  • 分治法基本思想: 将问题分解成多个子问题,并允许不断分解,使规模越来越小,最终可用已知的方法求解足够小的问题。  使用要求: (1) 问题能够按照某种方式分解成若干个规模较小、相互独立且与原问题类型...
  • 算法的基本思想-分治法 动态规划 贪心算法 回溯法 分支限界法 一、分治法->互不相交的子问题 基本思想:将一个难以解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。 典型代表:归并排序 ...
  • 分治法之快速排序算法解题思路

    千次阅读 2018-06-10 14:24:04
    快速排序算法的基本思想是:先找一个基准元素(比如待排序数组的第一个元素),进行一趟快速排序,使得该基准元素左边的所有数据都它小,而右边的所有数据都它大,然后再按此方法,对左右两边的数据分别进行快速排序...
  • 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。 分治法解题的一般步骤: (1)分解,将要解决的问题划分成若干...
  • 矩阵相乘分治法

    2016-12-07 10:31:27
    实验目的:掌握分冶策略的基本思想以及用分冶解决问题的一般技巧.运用编程工具,并运用分冶来解决矩阵乘法问题; 2.实验内容:设A 和 B 是两个n * n阶矩阵,求它们的乘积矩阵C。这里,假设n是2的幂次方;
  • 分治法(Divide and Conquer)也是一种解决问题的常用模式,分治法的设计思想是将无法着手解决的大问题分解成一系列规模较小的相同问题,然后逐个解决小问题,即所谓分而治之。分治法产生的子问题与原始问题相同,...
  • 分治法的概念以及应用

    千次阅读 2017-12-05 20:05:27
    分治法:“分久必合,合久必分” 哈哈,其实分治法应该理解为分而治之的方法,它的基本思想是把一个大的问题比较复杂的问题,拆分成多个规模较小的子问题,然后解决这些子问题的难度就比原来大的问题简单的多。...
  • 分治算法基本思想

    千次阅读 2018-03-14 17:09:53
    假定要寻找子数组S[low…high]的最大子数组,使用分治法将数组分解成两个尽可能想相等的子数组,找到子数组中点mid,则S[low…high]中任何连续数组S[i…j]必然是一下三种情况之一: l 完全位于S[low…mid]中,low≤...
  • java 快速排序 折半查找的界面实现 (递归与分治法
  • 题目: 给定一个长度为N的int型数组a[0, 1, 2, …, N-1],当i < j且a[i] > a[j],则称a[i]与a[j]是一对逆序对。求该数组的逆序对数量。 思路: ...// 借用归并排序算法实现分治法求数组的逆序对
  • 常用算法思想(一)——分治法

    千次阅读 2019-02-22 18:50:23
    “分而治之”( Divide and conquer)方法(又称“分治术”) ,是有效算法设计中普遍采用的一种技术。 所谓“分而治之” 就是把一个复杂的算法问题按一定的“分解”方法分为等价的规模较小的若干部分,然后逐个解决,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,890
精华内容 9,956
关键字:

分治法的基本思想