一、
递归:
直接或间接地调用自身的算法称为递归算法。用函数自身给出定义的函数称为递归函数。
分治:
分治法的基本思想是将一个规模为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)。