前言
分治算法是将一个大问题,分解成若干个小问题,再将小问题合并成如干个大问题。也是以中递归的方法。
一、分治
分治方法如上图所示,分是将一个大问题 分解成子问题,治就是处理分开后的若干个小问题,然后将处理后的问题合并返回。最常见的分治算法就是归并排序。如下图所示:
先将数组分解一个元素,一个数字是有序的,然后合并另一个数字,保证两个数字有序,然后依次类推。得到这个数组有序。
下面我们开看看代码.
二、LeetCode 例题
1.归并排序
这并不是一道例题,而是使用分治实现的 排序算法,我们来理解一下它。‘’
代码:
import random
class Solution:
def merge(self,left_list,right_list):
#存放合并后的结果
result = [] #辅助数组
l,r = 0,0
while l<len(left_list) and r <len(right_list):
if left_list[l]<= right_list[r]: # 从小到大排序 需要自己改了试试
result.append(left_list[l])
l+=1
else:
result.append(right_list[r])
r+=1
#合并剩下的
result+=left_list[l:]
result += right_list[r:]
return result
def merge_sort(self,nums):
#递归出口
if len(nums) <= 1 :
return nums
mid = len(nums)//2
#分治左边
left_list = self.merge_sort(nums[:mid])
#分治右边
right_list= self.merge_sort(nums[mid:])
#合并有序
return self.merge(left_list,right_list)
if __name__ == "__main__":
s = Solution()
# 生成长度为20的随机数测试
mylist = [random.randint(0,1000) for i in range(20)]
print("排序前:",mylist)
result = s.merge_sort(mylist)
print("排序后:",result)
2.169.多数元素
该题比较简单,主要是统计数组中数量最多的元素,可以使用其他方法,但这里需要用分治的思想来解答题它。
# 解题思路:
1 将该问题 分解成很小问题,计算 右边最做的元素,计算左边最多的元素
2 最后汇总成 总的最多的元素
代码如下:
class Solution:
def majorityElement(self, nums: List[int]) -> int:
"""
# 将该问题 分解成很小问题,计算 右边最做的元素,计算左边最多的元素
# 最后汇总成 总的最多的元素
"""
# 现在要编写一个递归函数来做划分
def divide(left,right):
#当分治到只有一个元素的时候,直接返回该元素
if left == right:
return nums[left]
#计算中间,分治
middle = left +(right-left)//2
left_elem= divide(left,middle)
right_elem = divide(middle+1,right)
# 左右两遍是同一个元素
if left_elem == right_elem:
return left_elem
#计算左边最多的个数
left_more = self.count(nums,left,middle,left_elem)
#计算右边大多数
right_more = self.count(nums,middle+1,right,right_elem)
#判断左边大还是右边大犯规元素
return left_elem if left_more >right_more else right_elem
return divide(0,len(nums)-1)
# 所以我们需要一个汇总的函数
def count(self,nums,left,right,elem):
count = 0
for i in range(left,right+1):
if nums[i] == elem:
count+=1
return count
总结
由于自己理解的程度不是很够,目前只写了这两道题,后续有理解深入后会引入更多的例子。