![《算法设计与分析基础》(Python语言描述) 课件 第4章分治法2_第1页](http://file4.renrendoc.com/view8/M00/32/2E/wKhkGWcdoQqAJ4cHAADqA5doBv0537.jpg)
![《算法设计与分析基础》(Python语言描述) 课件 第4章分治法2_第2页](http://file4.renrendoc.com/view8/M00/32/2E/wKhkGWcdoQqAJ4cHAADqA5doBv05372.jpg)
![《算法设计与分析基础》(Python语言描述) 课件 第4章分治法2_第3页](http://file4.renrendoc.com/view8/M00/32/2E/wKhkGWcdoQqAJ4cHAADqA5doBv05373.jpg)
![《算法设计与分析基础》(Python语言描述) 课件 第4章分治法2_第4页](http://file4.renrendoc.com/view8/M00/32/2E/wKhkGWcdoQqAJ4cHAADqA5doBv05374.jpg)
![《算法设计与分析基础》(Python语言描述) 课件 第4章分治法2_第5页](http://file4.renrendoc.com/view8/M00/32/2E/wKhkGWcdoQqAJ4cHAADqA5doBv05375.jpg)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
4.1分治法概述4.2求解排列问题CONTENTS提纲4.3求解查找问题4.4求解组合问题第4章分而治之—分治法1/33给定一个含n(n≥1)个整数的序列,要求求出其中最大连续子序列的和。序列(-2,11,-4,13,-5,-2)的最大连续子序列和为20。序列(-6,2,4,-7,5,3,2,-1,6,-9,10,-2)的最大连续子序列和为16。规定一个序列最大连续子序列和至少是0,如果小于0,其结果为0。4.4.1最大连续子序列和4.4求解组合问题2/33alow
…
ai
…
amidamid+1
…
aj
…
ahighmaxLeftSummaxRightSum(a)递归求出maxLeftSum和maxRightSummax3(maxLeftSum,maxRightSum,maxLeftBorderSum+maxRightBorderSum)(c)求出a序列中最大连续子序列的和alow
…
amid
amid+1…
ahighmaxLeftBorderSummaxRightBorderSum+(b)求出maxLeftBorderSum+maxRightBorderSum解3/33-20111-42133-54-25midmaxLeftSum=11maxRightSum=13(a)递归求出maxLeftSum和maxRightSummaxLeftBorderSum=7-201112133-54-25-4-475maxRightBorderSum=131386(b)以-4为中心的最大连续子序列和为20(c)结果=max3(11,13,20)=20示例4/331 defmaxSubSum51(a,low,high): #分治算法2 iflow==high:returnmax(a[low],0) #子序列只有一个元素时3 mid=(low+high)//2 #求中间位置4 maxLeftSum=maxSubSum51(a,low,mid)
#求左边的最大连续子序列之和5 maxRightSum=maxSubSum51(a,mid+1,high)
#求右边的最大连续子序列之和5/336 maxLeftBorderSum,lowBorderSum=0,07 foriinrange(mid,low-1,-1): #求左段a[i..mid]最大和8 lowBorderSum+=a[i]9 maxLeftBorderSum=max(maxLeftBorderSum,lowBorderSum)10 maxRightBorderSum,highBorderSum=0,011 forjinrange(mid+1,high+1): #求右段a[mid+1..j]最大和12 highBorderSum+=a[j]13 maxRightBorderSum=max(maxRightBorderSum,highBorderSum)14 returnmax(max(maxLeftSum,maxRightSum),
maxLeftBorderSum+maxRightBorderSum)6/3316 defmaxSubSum5(a): #求a序列中最大连续子序列和17 returnmaxSubSum51(a,0,len(a)-1)7/33T(n)=1 当n=1T(n)=2T(n/2)+n
当n>1T(n)=O(nlog2n)算法分析8/33问题描述:给定一个含n(1≤n≤10^5)个整数的数组
nums,设计一个算法找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
例如,nums={-2,1,-3,4,-1,2,1,-5,4},答案为6,对应的连续子数组是{4,-1,2,1}。
要求设计如下方法:
def
maxSubArray(self,
nums:
List[int])
->
int4.4.2实战—最大子序列和(LeetCode53★)9/33采用4.4.1节的分治法思路,由于这里的最大连续子序列至少含一个元素,为此做两点修改:当区间nums[low..high]中只有一个元素时返回nums[low]。考虑最大连续子序列跨越中间位置nums[mid]元素时,左段的最大连续元素和maxLeftBorderSum初始值置为nums[mid],右段的最大连续元素和maxRightBorderSum初始值置为nums[mid+1]。最后返回3部分的最大值。解10/331 class
Solution:2
def
maxSubArray(self,
nums:
List[int])
->
int:3
n=len(nums)4
if
n==1:return
nums[0]5
return
self.maxSubSum51(nums,0,n-1)11/337
def
maxSubSum51(self,nums,low,high):
#分治算法8
if
low==high:return
nums[low]
#子序列只有一个元素时9
mid=(low+high)//2
#求中间位置10
maxLeftSum=self.maxSubSum51(nums,low,mid)
#求左边的最大连续子序列之和11
maxRightSum=self.maxSubSum51(nums,mid+1,high)
#求右边的最大连续子序列之和12/3312
maxLeftBorderSum,lowBorderSum=nums[mid],013
for
i
in
range(mid,low-1,-1):
#求nums[i..mid]的最大和14
lowBorderSum+=nums[i]15
maxLeftBorderSum=max(maxLeftBorderSum,lowBorderSum)16
maxRightBorderSum,highBorderSum=nums[mid+1],017
for
j
in
range(mid+1,high+1):
#求nums[mid+1..j]的最大和18
highBorderSum+=nums[j]19
maxRightBorderSum=max(maxRightBorderSum,highBorderSum)20
ans=max(max(maxLeftSum,maxRightSum),
maxLeftBorderSum+maxRightBorderSum)21
return
ans13/33上述程序提交结果为通过,运行时间为1580ms,消耗空间为29.9MB。14/33问题描述:给定一个大小为n的数组nums,设计一个算法求其中的多数元素。
多数元素是指在数组中出现次数大于
n/2
的元素。可以假设中给定的非空数组中总是存在多数元素。
例如数组为{3,2,3},结果为3。
要求设计如下方法:
def
majorityElement(self,
nums)
->
int:4.4.3实战—多数元素(LeetCode169)15/33nums[0..n-1]中一定存在多数元素。当n=1,nums[0]就是多数元素,否则针对nums[low..high]采用分治法策略如下:分解:求出mid=(low+high)/2,将nums[low..high]分解成两个子序列nums[low..mid]和nums[mid+1..high],即将整个问题分解为两个相似的子问题。求解子问题:求出nums[low..mid]中多数元素为leftmaj,求出nums[mid+1..high]中多数元素为rightmaj。合并:如果leftmaj=rightmaj,则它一定就是nums[low..high]的多数元素。否则求出leftmaj在nums[low..high]的出现次数leftcnt,rightmaj在nums[low..high]的出现次数rightcnt,若leftcnt>rightcnt,则leftmaj是多数元素,否则rightmaj是多数元素。解16/331 class
Solution:2
def
majorityElement(self,
nums)
->
int:3
n=len(nums)4
if
n==1:return
nums[0]5
return
self.majore(nums,0,n-1);17/337
def
majore(self,nums,low,high): #分治算法8
if
low==high:return
nums[low]9
mid=(low+high)//210
leftmaj=self.majore(nums,low,mid)11
rightmaj=self.majore(nums,mid+1,high)18/3312
if
leftmaj==rightmaj:13
return
leftmaj14
else:15
leftcnt=016
for
i
in
range(low,high+1):17
if
nums[i]==leftmaj:leftcnt+=118
rightcnt=019
for
i
in
range(low,high+1):20
if
nums[i]==rightmaj:rightcnt+=121
if
leftcnt>rightcnt:return
leftmaj22
else:return
rightmaj19/33上述程序提交结果为通过,运行时间为104ms,消耗空间为17MB。20/33问题描述:含n个整数数组nums(0≤n≤3000,-10^5≤nums[i]≤10^5)。设计一个算法判断nums中是否存在三个元素a,b,c,使得a+b+c=0成立。要求找出所有和为0且不重复的三元组。
例如,nums={-1,0,1,2,-1,-4},结果为{{-1,-1,2},{-1,0,1}}。
要求设计如下方法:
def
threeSum(self,
nums)
->
List[List[int]]:4.4.4实战—三数之和(LeetCode15★★)21/33解以例4-2为基础,先将nums数组元素递增排序。用i遍历nums,对于每个nums[i],在nums[i+1..n-1]中查找元素和为-nums[i]的元素对,再加上nums[i]构成一个满足要求的三元组,对于每个元素都需要跳过重复的元素。22/331 class
Solution:2
def
threeSum(self,
nums:
List[int])
->
List[List[int]]:3
n,ans=len(nums),[]4
if
n<3:return
ans
#长度小于3,返回空表5
nums.sort()
#对nums递增排序6
if
nums[0]>0:return
ans
#首元素大于0,返回空表23/337
for
i
in
range(0,n-2):
#遍历nums[i]8
if
i>0
and
nums[i]==nums[i-1]:continue #跳过重复的元素nums[i]9
low,high=i+1,n-124/3310
while
low<high:11
sum=nums[low]+nums[high]12
if
sum<-nums[i]:low+=1
#和太小,向右移动13
elif
sum>-nums[i]:high-=1 #和太大,向左移动14
else:
#找到一个三元组tmp15
tmp=[nums[i],nums[low],nums[high]]16
ans.append(tmp)
#将tmp添加到ans中17
low+=118
while
low<high
and
nums[low]==nums[low-1]:
19
low+=1 #跳过重复的元素nums[low]20
high-=121
while
low<high
and
nums[high]==nums[high+1]:22
high-=1 #跳过重复的元素nums[high]23
return
ans25/33上述程序提交结果为通过,运行时间为1056ms,消耗空间为18.1MB。26/33【问题描述】给定若干个二维空间中的点,点集采用数组p存放,任意两个不同点之间有一个直线距离,求最近的两个点的距离。4.4.5求最近点对距离27/33对p中所有点按x坐标递增排序,采用分治法策略求解。解S1S2p[mid].xd3垂直带形区ddPLPRXYdld2d=min(d1,d2)d=min(d,d3)28/33ddPLlPRdp1[i]p1中的点按y递增排序。p1中每个点p1[i]在y方向d距离内最多7个点与它的距离小于d。按y递增排序29/331 defdis(a,b): #求两个点之间的距离2 returnmath.sqrt(float(a[0]-b[0]
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五珠海二手房买卖合同模板:针对拆迁补偿房产交易3篇
- 2025电力企业职业病防治责任制度
- 淘宝主要各行业销售额明细数据分析课件
- 《软件设计的任务》课件
- 《科研标书撰写》课件
- 《金融工程案例分析》课件
- 《高等数学格林公式》课件
- 2025至2031年中国常规生物正置显微镜行业投资前景及策略咨询研究报告
- 《汽车基础知识》课件
- 2025至2031年中国丙烯酸内墙耐水腻子行业投资前景及策略咨询研究报告
- 部编版《语文》三年级下册全册教案及反思
- 风电场工程强制性条文执行计划
- 茶叶的起源与发展
- 2023-2024学年天津市小学数学二年级上册期末高分试卷
- 工程造价绩效考核KPI指标库
- 罗姓姓氏源流和迁徙分布
- GB/T 4662-2012滚动轴承额定静载荷
- 房屋建筑学-01概论
- 2023年大唐集团招聘笔试试题及答案新编
- 法律专题(本)(52876)-国家开放大学电大学习网形考作业题目答案
- 班前安全活动记录(防水工)
评论
0/150
提交评论