分治算法:
what: 是一个将母问题分为相同子问题来简化计算的算法
How: 基本有三步,
- 将问题转化为相同的小问题
- 递归解相同的小问题
- 将上述小问题的结果综合并返回
Why:
主要是重复利用堆栈,效率上的提升主要是针对计算数量级逐级快速递增的,解决的问题主要是计算量大
POW(X,n)
1 | class Solution: |
注意:
从解决问题的角度,算法只用
1 | def myPow(self, x: float, n: int) -> float: |
但是会导致一个问题
递归的栈爆了,采取稍微减少点
1 | def myPow(self, x: float, n: int) -> float: |
53. 最大子序和
分治思路:
一个序列中的最大子序列和可以分为三个部分, 左半部分的子序列和,右半部分的子序列和,从中间开始的最大子序和
1 | class Solution: |
这个算法不是很好,计算的复杂度还是O(n)的,因为每一次的决策是否加入后面的序列可以根据上一次的计算结果,采用动态规划也可以, 提前算好每一次前几个序列和和,还可以减少空间复杂度
1 | class Solution: |
169. 多数元素
对于这种求出现次数的问题,python中collection模块中的Count 很好用, 但是本文没有使用该方法,一个简单的思路是用一个dict来统计出现的次数,然后便利这个字典求出最大次数的即可
1 | class Solution: |
但是这个不是我们的目标,我们的目标是学会利用分治的思想
传统的分治思想对于数组来说,基本上就是从空间上划数组的范围达到分解问题再组合,这个题目其实利用了一个假设,就是如果一个数字出现的次数最多,要么在左边数量最多,要么在右边数量最多
按照这个假设就可以做题了,首先分为两个部分,然后再来求两边的哪一个最大,如果分到只剩下这一个就返回这个数值
1 | def majorityElement(self, nums) -> int: |
使用分治的算法其实相比哈希的方法更慢,因为最后都有个查询次数的遍历,反而计算量更大
最佳的办法还是使用Conter 方法最快,然后使用most_commen 函数找最常见的,然后返回
1 | from collections import Counter |
还有利用条件n/2 的,先排序再取中间值,虽然速度很快,但是计算复杂度是nlog(n)的,速度快只是运气好主频高而已