分治
LeetCode练习:分治
分治(分而治之)是将一个规模较大的问题拆分成几个小问题,然后求解规模较小的小问题,最后将每个小问题的解合并,即得到大问题的解
个人感觉在解决问题中使用分治思想的难点在于
- 证明能够使用分治算法的可行性
- 在得到小问题的解后如何将小问题的解合并
分治算法的主要实现手段是递归
归并排序
最经典的应用分治算法的例子就是归并排序
from math import floor
def mergesort(arr):
if len(arr) < 2:
return arr
else:
middle = floor(len(arr) / 2)
left = arr[0:middle]
right = arr[middle:]
return merge(mergesort(left), mergesort(right))
def merge(left, right):
result = []
while left and right:
if left[0] <= right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
while left:
result.append(left.pop(0))
while right:
result.append(right.pop(0))
return result
以下是练习题目:
1.求众数
在一个数组中找到出现次数最多的元素
思路:
- 确定拆分的终止条件
- 将数组一分为二,直到满足终止条件
- 处理子问题得到子结果,并合并:
- 数组长度为1,则输出数组
- 若left == right, 则输出left
- 若arr.count(left) > arr.count(right), 则输出left
- 否则输出right
'''
用分治的思想求数组中的众数
'''
from math import floor
def findmode(arr):
if len(arr) < 2:
return arr[0]
else:
middle = floor(len(arr)/2)
left = findmode(arr[0 : middle])
right = findmode(arr[middle : ])
return merge(left, right, arr)
def merge(left, right, arr):
if left == right:
return left
elif arr.count(left) > arr.count(right):
return left
else:
return right
print(findmode([1,1,2,3,4,5]))
2.最大子序列和
求出一个数组的子序列中,和最大的子序列,输出和
思路:
- 确定终止条件
数组长度为1时,终止拆分 - 拆分问题
将数组一分为二,直至满足终止条件 - 求出子问题的解,合并子问题的解
- 合并
- 从右到左求出left数组的最大子序列和
- 从左到右求出right数组的最大子序列和
- 合并两个子序列
- 输出左区间,右区间以及合并的子序列的最大值
- 合并
'''
给定一个整数数组,找到一个具有最大和的连续子数组
'''
def maxsubarray(arr):
if len(arr) < 2:
return arr[0]
else:
middle = len(arr)//2
left = maxsubarray(arr[ : middle])
right = maxsubarray(arr[middle : ])
max_l = arr[len(arr)//2-1]
tmp = 0
for i in range(len(arr)//2-1, -1, -1):
tmp += arr[i]
max_l = max(tmp, max_l)
max_r = arr[len(arr)//2]
tmp = 0
for i in range(len(arr)//2, len(arr)):
tmp += arr[i]
max_r = max(tmp, max_r)
return max(left, right, max_l+max_r)
print(maxsubarray([-2,1,-3,4,-1,2,1,-5,4]))
3.实现pow(x, n)
'''
实现计算x的n次幂函数
'''
def mypow(x, n):
if n < 0:
x = 1/x
n = -n
if n == 0:
return 1
if n%2 == 1:
p = x * mypow(x, n-1)
return p
return mypow(x*x, n/2)
print(mypow(2, 10))

浙公网安备 33010602011771号