《算法设计与分析》之分治法

递归分治法实现有重复元素的排列问题 书上例题: 1.问题描述         设集合R={r1,r2,...,rn}是要进行排列的n个元素,其中r1,r2,...,rn可能相同。 试着设计一个算法,列出R的所有不同排列。 即,给定n以及待排的n个可能重复的元素。计算输出n个元素的所有不同排列。 2.算法设计         给定n及待排列的n个元素,计算出这n个元素的所有不同排列。 3.数据输入         第1 阅读详情

目录

分治法的定义:

分治法的适用条件:

分治法的求解过程:

分治法的具体应用案例:

1、快速排序和归并排序:

2、求解查找问题:

3、求解最大连续子序列和问题:


分治法的定义:

将一个大规模问题分解成k个相互独立、规模较小且与原问题形式相同的子问题,递归的解决这些子问题,然后合并各个子问题的解,从而得到原问题的解。

分治法的适用条件:

1、问题的规模缩小到一定的程度就能很容易的解决。

2、问题可以分解成若干个相似且独立的小问题。

3、子问题的解可以合并为原问题的解。

分治法的求解过程:

1、分解成若干个子问题。

2、求解子问题。

3、合并子问题的解。

分治法的具体应用案例:

1、快速排序和归并排序:

快速排序定义:在待排序的n个元素中任取一个元素作为基准,把所有小于这个基准的元素放在它的前面,形成一个新的子序列,把所有大于这个基准的元素放在它的后面,形成一个新的子序列。再对这两个子序列继续上述操作,直到每个子序列中只有一个元素为止。

快速排序过程演示(每次以数组的第一个元素为基准):

排序前:7        3        5        9        4        2

第一趟排序:2        3        5        4        7        9

第二趟排序:2        3        5        4        7        9

第三趟排序:2        3        5        4        7        9

第四趟排序:2        3        4        5        7        9

快速排序代码展示:

package test;

public class Test {
	public static void main(String[] args) {
		int[] a= {7,3,5,9,4,2};
		sort(a,0,a.length-1);
		for(int i=0;i<a.length;i++)
			System.out.println(a[i]);
	}
	private static void sort(int[] nums,int L,int R) {
		if(L>=R)
			return ;
		int left=L,right=R;
		int p=nums[left];
		while(left<right) {
			while(left<right&&p<nums[right])
				right--;
			if(left<right) {
				nums[left]=nums[right];
				nums[right]=p;
				left++;
			}
			while(left<right&&p>nums[left])
				left++;
			if(left<right) {
				nums[right]=nums[left];
				nums[left]=p;
				right--;
			}
		}
		sort(nums,L,left-1);
		sort(nums,right+1,R);
	}
}

归并排序定义:先将整个数组看成n个长度为1的有序表,将相邻的k(k>=2)个有序子表成对归并,得到n/k个长度为k的有序子表;然后继续将这些有序子表归并,得到n/(k*k)个长度为k*k的有序子表,直到最后得到1个长度为n的有序表。

归并排序过程演示(取k=2):

排序前:7        3        5        9        4        2

第一趟排序:3        7        5        9        2        4

第二趟排序:3        5        7        9        2        4

第三趟排序:2        3        4        5        7        9

归并排序代码展示:

package test;

public class Test {
	public static void main(String[] args) {
		int[] a= {7,3,5,9,4,2};
		sort(a,0,a.length-1);
		for(int i=0;i<a.length;i++)
			System.out.println(a[i]);
	}
	private static void sort(int[] nums,int L,int R) {
		if(L>=R)
			return ;
		int mid=(L+R)/2;
		sort(nums,L,mid);
		sort(nums,mid+1,R);
		int[] temp=new int[(R-L+1)];
		int i=L,j=mid+1,k=0;
		while(i<=mid&&j<=R) {
			if(nums[i]<nums[j])
				temp[k++]=nums[i++];
			else
				temp[k++]=nums[j++];
		}
		while(i<=mid)
			temp[k++]=nums[i++];
		while(j<=R)
			temp[k++]=nums[j++];
		for(i=L,k=0;k<temp.length;i++,k++)
			nums[i]=temp[k];
	}
}

2、求解查找问题:

LeetCode第215题 找出数组中的第k个最大元素

思路:采用类似快速排序的思想。与快速排序的区别为:1、每趟排序都会丢掉一部分元素;2、找到所求元素立即停止排序。

完整代码展示:

package leetcode_7;

public class T_215 {
	public static void main(String[] args) {
		int[] a= {3,2,3,1,2,4,5,5,6};
		System.out.println(findKthLargest(a,4));
	}
	public static int findKthLargest(int[] nums, int k) {
		return sort(nums,0,nums.length-1,k);
	}
	private static int sort(int[] nums,int L,int R,int k) {
		if(L==R)
			return nums[L];
		int left=L,right=R,p=nums[left];
		while(left<right) {
			while(left<right&&p>nums[right])
				right--;
			if(left<right) {
				nums[left]=nums[right];
				nums[right]=p;
				left++;
			}
			while(left<right&&p<nums[left])
				left++;
			if(left<right) {
				nums[right]=nums[left];
				nums[left]=p;
				right--;
			}
		}
		if(left==k-1)
			return nums[k-1];
		else if(left>k-1)
			return sort(nums,L,left-1,k);
		else
			return sort(nums,left+1,R,k);
	}
}

LeetCode第4题 寻找两个正序数组的中位数

思路:先确定中位数在这两个数组中排第几,如:数组1的长度为5,数组2的长度为8,则中位数排在第7位;数组1长度为5,数组2长度为7,则中位数排在第6位和第7位中间,故应该先求出这两个数,然后求均值。然后写一个求两个有序数组第k小元素的函数。

完整代码展示:

package leetcode_7;

import java.util.Arrays;

public class T_4 {
	public static void main(String[] args) {
		int[] a= {1,2,5,8,0};
		int[] b= {3,4,6,9,12};
		System.out.println(findMedianSortedArrays(a,b));
	}
	public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
		int m=nums1.length,n=nums2.length;
		int k=(m+n)/2;
		if((m+n)%2==1)
			return	f(nums1,m,nums2,n,k+1);
		return	(f(nums1,m,nums2,n,k)+f(nums1,m,nums2,n,k+1))/2;
	}
	private static double f(int[] a,int al,int[] b,int bl,int k) {
		if(al>bl)//f函数用于找两个有序数组中第k小的元素
			return f(b,bl,a,al,k);
		if(al==0)
			return b[k-1];
		if(k==1)
			return a[0]<=b[0]?a[0]:b[0];
		int na=al>=k/2?k/2:al;
		int nb=k-na;
		if(a[na-1]==b[nb-1])
			return a[na-1];
		else if(a[na-1]<b[nb-1]) {
			int[] temp=new int[al-na];
			for(int i=na,j=0;i<al;i++,j++)
				temp[j]=a[i];
			return f(temp,al-na,b,bl,k-na);
		}
		else {
			int[] temp=new int[bl-nb];
			for(int i=nb,j=0;i<bl;i++,j++)
				temp[j]=b[i];
			return f(a,al,temp,bl-nb,k-nb);
		}
	}
}

3、求解最大连续子序列和问题:

LeetCode第53题 最大子数组和

剑指 Offer 42 连续子数组的最大和

思路:将数组分成3部分,从左半部分的最大和,右半部分的最大和和从中间向两边延伸的最大和中选取最大值即为答案。而左半部分求最大和与右半部分求最大和又可以各自分成3部分,一直递归下去,直到数组中只有一个值,若为正数则直接返回该值,否则返回0。最开始分组之前要保证原始数组中的元素不全为负数。

完整代码展示:

package leetcode_7;

public class T_O_42 {
	public static void main(String[] args) {
		int[] a= {-2,1,-3,4,-1,2,1,-5,4};
		System.out.println(maxSubArray(a));
	}
	public static int maxSubArray(int[] nums) {
		int max=nums[0];
		for(int x:nums)
			if(max<x)
				max=x;
		if(max<0)
			return max;
		return maxSum(nums,0,nums.length-1);
	}
	private static int maxSum(int[] nums,int L,int R) {
		if(L==R)
			return nums[L]>0?nums[L]:0;
		int mid=(L+R)/2;
		int leftSum=maxSum(nums,L,mid);
		int rightSum=maxSum(nums,mid+1,R);
		int midSum=0,count=0;
		for(int i=mid;i>=L;i--) {
			count+=nums[i];
			midSum=Math.max(count, midSum);
		}
		count=midSum;
		for(int i=mid+1;i<=R;i++) {
			count+=nums[i];
			midSum=Math.max(count, midSum);
		}
		int max=Math.max(leftSum, rightSum);
		max=Math.max(max, midSum);
		return max;
	}
}

算法设计与分析——分治法 算法思想: “分而治之”。把一个复杂的问题分成两个或更多的相同问题,直到最后各个子问题可以简单的直接求解,对各个子问题的解进行合并即得原问题的解。 工作方案: 1.将问题的实例划分为同一个问题的几个较小的实例,最好拥有同样的规模。 2.对这些较小的实例求解。(一般使用递归的方法)。 3.如果有必要,合并这些较小规模的解,以得到原问题的解。 分治法孕育了计算机科学中许多最重要 阅读详情

相关推荐

c语言 分治法 算法设计与分析

对于一个规模为n的问题,若该问题可以容易地解决(例如规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解决这些子问题,然后将各个子问题的解合并得到原问题的解,这种算法设计策略叫分治法。 分治法所能解决的问题一般具有以下几个特征: (1)该问题的规模缩小到一定的程度就可以容易地解决。 (2)该问题可以分解为若干个规模较小地相似问题。 (3)利用该...

weixin_44855697的博客 524

算法应用之分治法

一、分治法的基本概念 在生活中当我们遇到复杂的问题时,我们通常会将这个复杂的问题分为几个小的问题或者分为几个步骤来解决,当我们将原问题拆分成若干个小问题或者步骤过后,小问题相对原问题来讲或许会更容易解决,我们通过解决这些小问题,最终达到解决该问题的目的。 这种解决问题的思想就类似于计算机科学中的“分治法”。分治即“分而治之”,一个规模很大的问题若要直接求解起来是...

zcczero的博客 3356

分治法范式在算法设计中的应用与分析

本文深入探讨了分治法在算法设计中的多种应用,包括排序、查找、数学问题求解等场景。通过对一系列练习题的分析,阐述了分治法的基本原理和时间复杂度的计算方法。文章通过具体示例详细说明了如何利用分治法解决各类问题,并对解决这些问题的算法进行了时间复杂度的分析。

weixin_32673065的博客 317

分治算法思想及应用

一. 分治算法介绍 1. 分治算法思想 2. 分治算法适用条件 3. 分治算法的引入 二. 分治算法的应用 1. 快速排序 2. 快排划分函数求topk问题 3. 归并排序 4. 合并k个有序单链表 5. 对数时间求中位数算法思想

qq_41721746的博客 5040

告别wx.showActionSheet:微信小程序自定义底部弹框的5种实现方式对比

本文深入对比了微信小程序中替代原生wx.showActionSheet的五种自定义底部弹框实现方案。从基础视图层模拟到组件化封装,再到利用第三方UI库、CSS3动画及Page-Meta组件,详细分析了各方案的优缺点与适用场景,旨在帮助开发者根据项目需求,选择最合适的方案以实现高度定制化、交互丰富的弹框效果。

weixin_29005499的博客 190

STM32超声波避障小车硬件设计与实时测距实现

超声波测距是嵌入式系统中经典的环境感知技术,其原理基于声波在空气中的传播时间与距离的线性关系,通过精确计时实现非接触式距离测量。该技术具备成本低、抗光干扰强、算法简洁等优势,广泛应用于智能小车、机器人避障、液位监测等场景。工程落地的关键在于硬件信号完整性(如5V/3.3V电平匹配)、微秒级定时精度(依赖高稳定外部晶振与输入捕获模式)以及强干扰环境下的数据鲁棒性(需软硬协同滤波)。本文以STM32F103C8T6为平台,深入解析HC-SR04模块的时序闭环控制、TIM3输入捕获双沿测量、L298N电机状态机驱

weixin_42578963的博客 295

分治法思想的介绍(大整数的乘法,Strassen矩阵乘法,棋盘覆盖问题,二分搜索,快速排序,合并排序,线性时间选择)

分治法基本思想 将一个难以直接解决的大问题,分割成一些规模较小的k个相同问题,以便·各个击破,分而治之·。 对这k个子问题分别求解。如果子问题的规模仍然不够小,则再划分为若干个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。 将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。  递归是实现分治算法思想的技术。????查看递归的介绍  合并排序的例子 分治法的适用条件 分治法所能解决的问题一般具有以下几个特征: 该问题的规模缩小到一定的程度就可以

迷雾总会解 1898

基于STM32的智能水温控制系统设计

智能水温控制系统广泛应用于家庭、工业、农业等多个场景,尤其在热水器、恒温泳池和地暖系统中,通过实时监测和调节水温,提高设备的效率和用户的舒适度。本文基于STM32微控制器设计了一个智能水温控制系统,能够实时监测水温、用户设置温度,并根据需要控制加热器或冷却装置,确保水温维持在设定范围内。系统能够根据用户设定自动控制加热和冷却设备,确保水温维持在舒适的范围内,并通过OLED屏实时显示水温信息。在生成的项目基础上,编写水温监测、目标温度设定、加热器和冷却装置控制、OLED数据显示以及超温报警的代码。

2401_88410555的博客 2475

算法-分治法(Divide-and-Conquer)

算法-分治法(Divide-and-Conquer) 分治法简介 分治法是把一个复杂的问题分成两个或多个相同或相似的子问题,再把子问题分成更小的子问题直到最后子问题可以简单地直接求解,原问题的解即子问题的解的合并,这个思想是很多高效算法的基础。 分治法的基本思想:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。 分治策略 分治策略:对于一个规模为n的问题, 若该...

qq_36629741的博客 861

【Flink】Flink提交任务到Yarn报错Unable to close file because the last blockBP enough number of replicas

当使用 HDFS 存储文件时,每个数据块会有多个副本分布在不同的节点上,以确保数据的可靠性和容错性。然而,由于某种原因,最后一个数据块 blk_1101776325_28036289 的副本数量不足,导致无法成功关闭文件。如果确定副本数量正确,并且问题仍然存在,可以尝试手动修复副本不足的情况。异常消息表明在关闭文件时出现问题,我的原因是hadoop上有个节点有问题,导致提交到那个节点的时候,无法传递包到相关的机器上。检查 HDFS 集群的状态,确保所有节点都正常工作,没有节点宕机或网络故障等问题。

九师兄 935

【重温童年】基于tkinter模块设计的Q宠大乐斗武器升星模拟器:重温经典,畅享休闲时光

与传统的Q宠大乐斗不同,这款模拟器还加入了一个创新的功能——自定义升星概率。玩家可以根据自己的喜好和策略,为不同的武器设置不同的成功率和降级率。比如,你可以将“嗜血”这把武器的升星难度设置得极高,以体现其稀有性和强大威力;也可以将“平底锅”这样的普通武器设置得相对容易升星,让玩家在升级过程中感受到更多的成就感。这种自定义的概率设置,不仅增加了游戏的趣味性和挑战性,还让玩家在升级过程中有了更多的策略和选择。你可以根据自己的武器库和卷轴数量,制定出最合适的升级计划,从而在游戏中占据先机。

nmdbbzcl的博客 1237

算法设计与分析之分治法

将一个复杂的问题分解成若干个规模较小、相互独立,但类型相同的子问题求解;然后再将各子问题的解组合成原始问题的一个完整答案,这样的问题求解策略就叫分治法。

qq_44075108的博客 6588

论文复现《基于最大李雅普诺夫指数的电力系统暂态电压稳定评估方案》

电力系统暂态电压稳定评估方案 摘要 本研究提出了一种基于最大李雅普诺夫指数的电力系统暂态电压稳定评估方法。通过分析相空间中相邻轨迹的收敛或发散特性,该方法能够提前判别系统稳定性。论文首先阐述了暂态电压稳定机理,详细介绍了最大李雅普诺夫指数的计算方法。针对IEEE-39节点系统,建立了仿真模型并获取不同故障场景下的数据。研究开发了完整的评估程序,包括数据预处理、相空间重构、指数计算等模块,并通过与时域仿真结果的对比验证了方法的准确性。实验结果表明,该方法能够快速有效地评估电力系统的暂态电压稳定性,为系统安全运

max500600的博客 187

算法设计与分析第三章:分治法

算法分析与设计实验报告 第 三 次实验 姓名 裴朵朵 学号 5001170016 班级 计科一班 时间 2019.10 地点 实验名称 分治法及其应用 实验目的 1、理解分治法的概念、原理方法。 2、掌握分治法的使用规律与编程技巧 3.能够应用分治法求解日常生活中问题 实验原理 1.设计一个算法,利用分治法求一个整数序列中的最大和最小元素 2.设计一个算法,采用分治法求x^n 3.有n个互不相同的...

qq_42339734的博客 9818

利用 Python 构建高效爬虫爬取国家标准文献——从基础到进阶

然而,由于许多标准文献需要从特定网站获取,手动下载既耗时又低效,因此构建自动化爬虫成为一种实用且高效的解决方案。本文从技术选型、网站分析、代码实现到反爬优化,全面讲解了如何爬取国家标准文献。国家标准文献(National Standards Literature)是国家对各领域统一规范的文件,涵盖了技术参数、测试方法、生产工艺等内容。因此,通过自动化爬虫技术进行文献爬取和管理,不仅能解放劳动力,还可以提高数据管理效率。在构建爬虫前,我们需要对目标网站进行分析,包括页面结构、请求方式以及可能的反爬机制。

2201_76125261的博客 2104

Pre-suite 开发之MFi功能搭建

Pre-suite 固件中只有带无线硬件的Ezairo 7160sl才具备无线通信能力,其无线功能包括标准BLE 5.2 低功耗蓝牙功能以及非标准的低功耗无线音频流功能。Ezairo 7160sl 支持3种低功耗无线音频流协议:来自APPLE的MFi,来自Google的ASHA以及来自onsemi的remote mic。其中MFi音频流走的G.722编码的Mode1,速率为64kbps;而非MFi音频流走的G.722的Mode3,速率为48kbps.

SnowYang2017的博客 1501

算法设计与分析之“分治法”

有关算法设计中分治法的详细介绍,欢迎观看。

2401_83201682的博客 1041

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

分治法实验之大整数乘法(算法设计分析)

分治法实验之大整数乘法01. 问题描述02. 输入格式03. 输出格式04. 输入样例05. 输出样例06. 问题分析07. 算法设计08. 代码实现09. 测试结果10. 复杂度分析 01. 问题描述 编写一个能计算两个n(16<=n<=256)位整数的乘法。 02. 输入格式 输入两行数据,每行表示一个大整数 03. 输出格式 输出运算后大整数的数据值 04. 输入样例 1111111111111111 1111111111111111 05. 输出样例 结果:123456

Aslixzhou 5515

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

算法设计与分析——递归与分治法策略总结

算法设计与分析——递归与分治法策略总结

Pumpkin_ln的博客 622

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

头歌之算法设计与分析-分治法

本关任务:对于给定的 n 个元素的数组a[0:n-1],要求从中找出第 k 小的元素。//表示给定10(n)个元素的数组,从中找出第5(k)小的元素。本关任务:利用分治法求一组数据中最大的两个数和最小的两个数。本关任务:利用分治法求一组数据的和。//此行及以下为具体的每个数据。//此行及以下为具体的每个数据。//此行及以下为具体的每个数据。分治法求出数组元素的和为:386。

2201_75304925的博客 620

高级算法分析与设计-分治法

【代码】高级算法分析与设计-分治法。

qq_53682472的博客 479

算法设计与分析—金块问题(分治法)

【老板有一袋金块(共n块),两名员工每人可以得到其中的一块,排名第一的员工可以得到最重的金块,排名最后的员工的则得到袋子中最轻的金块。】

考研小钻风 2746

算法分析与设计 分治法

算法分析与设计 分治法【快排C++实现】 [https://www.jianshu.com/p/d8eb716307e3]

Mr_Rong_的博客 168
上一篇: 《算法设计与分析》之递归
下一篇: 《算法设计与分析》之蛮力法
qq_60587708
博客等级 码龄5年 7粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值