算法 之 递归与分治策略

一、

递归:

直接或间接地调用自身的算法称为递归算法。用函数自身给出定义的函数称为递归函数。

分治:

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

可用分治的题目特点:

1、规模缩小到一定程度容易解

2、有最优子结构

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

4、子问题相互独立,不包含公共问题。

二、采用递归与分治策略 的例题:

1、最大子段和问题(leetcode 53
给定一个整数序列,找出一个具有最大和的连续子数组。比如:

输入:-2 1 -3 4 -1 2 1 -5 4

输出:6

解释:连续子段 4 -1 2 1 的和最大,为6。

分析:

首先平分原序列为两子序列,那么最大子序列只有下面三种情况:

1、出现在数组的左半部分

2、出现在数组的右半部分

3、出现在数组的中间部分,横跨左右两部分

分别计算以上三种可能情况对应的子序列和,比较大小得出结论,并进行递归。

例:       -2 1 -3 4 -1 2 1 -5 4

     -2 1 -3 4 -1                       2 1 -5 4

-2 1 -3        4 -1                 2 1        -5 4

-2 1    -3      4 -1              2   1            -5 4

2、第k个最大元素(leetcode 215)

在未排序的序列中找到第k个最大的元素,即倒数第k个数。

输入: 3 2 1 5 6 4 和 k=2    输出:5

解释:这6个数从小到大排是 1 2 3 4 5 6。所以倒数第2个数是5。

输入:3 2 3 1 2 4 5 5 6 和 k=4    输出:4

解释:这9个数从小到大排是 1 2 2 3 3 4 5 5 6,倒数第4个数是4。

要求:不允许使用排序算法。要求实现线性时间算法。

分析: 

 随机选择一个元素作为Flag,将小于该元素的元素放在Flag左侧,反之放在右侧,根据k以及新序列实际情况,对左侧部分或右侧部分进行递归。避免了完全的排序,时间复杂度为O(n)。

3、利用通项公式计算Fibonacci数列。

用分治法计算 Fibonacci数列的的第n项目。

指定计算实例:n=学号去掉所有0后取最低6位。输出20位整数,前10位是fib(n)的最高10位,后10位是fib(n)的最低10位。

例子:学号1973200098, n=973298

fib(973298)=7994568382...6610279649

所以输出为:79945683826610279649

分析:

重载运算符*,并编写一个递归该乘法的函数(快速幂乘)用以计算通项公式中的A与B,最终返回B即可;类似的编写一个乘法递归函数用以计算2的n-1次幂,最后编写主函数输出B除以2的n-1次幂即为所求。时间复杂度O(logn)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值