《图解算法》阅读08—分而治之的思想

分而治之(divide and conquer)是一种著名的递归式问题解决方法。

使用分而治之的思想解决问题的过程包括两个步骤:

  1. 找出基线条件,这种条件必须尽可能简单。
  2. 不断将问题分解(缩小规模),直到符合基线条件。

书中提出了几个具体的例子来解释分而治之的思想。如果有一个农场主,有一块地,我们如何让将这块地分成大小相同的方块,并且分出的方块要尽可能大。
首先,我们可以利用循环来解决这个问题。 把要分的小方块的边长当作循环变量,每次循环检查土地的边长是否为小方块边长的整数倍。分析到这里,博主突然发现,这个问题原来就是找出土地的两条边的最大公因数。
其次,书中提出了按照分而治之的思想想出的一种递归方式。
该算法的基础是欧几里得算法,“适用于这个小块地的最大方块,也是适用于整块地的最大方块”

  1. 找出基线条件。当一条边的长度是另一条边的整数倍时,就可以停止算法。
  2. 缩小问题的规模。首先找出这块地可以容纳的最大方块,然后对余下的土地调用算法。

D&C并非可用于解决问题的算法,而是一种解决问题的思路。

下面再看一个例子:给定一个数组对数组进行求和。
利用循环解决很简单,见代码实现,不再累述。

```python
#利用循环对数组进行求和
#python 3.7
#小灿 2018-12-3
def mysum(arr):
	total = 0
	for i in arr:
		total += i
	return total
print(mysum([1,2,3,4,5]))

如何使用递归函数来完成这个任务呢?
第一步 找出基线条件。我们知道最简单的数组是空数组或者是只有一个元素的数组,对这两种数序进行求和是非常简单的。

  1. 空数组,不包含任何元素,总和为0
  2. 单元素数组,只包含一个元素,总和为元素值

经过分析,基线条件就是上面的条件。
第二步 如何缩小问题规模呢?每次递归调用都减少数组元素的数目。
函数的工作原理如下所示。
在这里插入图片描述
一个特例函数的执行过程能够更好地帮助我们理解递归。
在这里插入图片描述
tips:涉及数组的递归函数时,基线条件是数组为空或只包含一个元素。
求和的递归实现过程如下。

```python
#利用递归对数组进行求和
#python 3.7
#小灿 2018-12-3
def mysum(arr):
	total = 0
	if len(arr) == 1:
		return arr[0]
	else:
		total = arr[0]+mysum(arr[1:len(arr)]) 
	return total
 
total = mysum(arr=[1,2,3,4,5])
print(str(total))

为了巩固对递归算法的理解,我们将进一步利用递归算法实现两个例子。一个是利用递归函数来计算列表中包含的元素数,第二个是找出列表中的最大的元素,由于都很简单,直接给出代码。

```python
#python 3.7
#小灿 2018-12-3
def mycount(arr):
	#利用递归计数
	if arr == []:
		return 0
	else:
		return 1 + count(list[1:])

def max(arr):
	#利用递归求最大值
	if len(arr) == 2:
		if arr[0] > arr[1]:
			return arr[0]
		else:
			return arr[1]
	else :
		sub_max = max(list[1:])
		if arr[0] > sub_max :
			return arr[0]
		else:
			return sub_max

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值