文章目录

  • 主要思想
    • 分治算法的步骤
    • 分治法适用的情况
    • 伪代码
  • 3道例题
    • 169.多数元素
    • 53.最大子序和
    • 50. Pow(x, n)

主要思想

分治算法的主要思想是将原问题递归地分成若干个子问题,直到子问题满足边界条件,停止递归。将子
问题逐个击破(一般是同种方法),将已经解决的子问题合并,最后,算法会层层合并得到原问题的答
案。

分治算法的步骤

  • 分:递归地将问题分解为各个的子问题(性质相同的、相互独立的子问题);
  • 治:将这些规模更小的子问题逐个击破;
  • 合:将已解决的子问题逐层合并,最终得出原问题的解

分治法适用的情况

  • 原问题的计算复杂度随着问题的规模的增加而增加
  • 原问题能够被分解成更小的子问题
  • 子问题的结构和性质与原问题一样,并且相互独立,子问题之间不包含公共的子子问题
  • 原问题分解出的子问题的解可以合并为该问题的解。

伪代码

def divide_conquer(problem, paraml, param2,...):# 不断切分的终止条件if problem is None:print_resultreturn# 准备数据data=prepare_data(problem)# 将大问题拆分为小问题subproblems=split_problem(problem, data)# 处理小问题,得到子结果subresult1=self.divide_conquer(subproblems[0],p1,..…)subresult2=self.divide_conquer(subproblems[1],p1,...)subresult3=self.divide_conquer(subproblems[2],p1,.…)# 对子结果进行合并 得到最终结果result=process_result(subresult1, subresult2, subresult3,...)

3道例题

169.多数元素

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

1.分治法

class Solution:def majorityElement(self, nums: List[int]) -> int:if not nums:return Noneif len(nums) == 1:return nums[0]# 【准备数据,并将大问题拆分为小问题】left = self.majorityElement(nums[:len(nums)//2])right = self.majorityElement(nums[len(nums)//2:])# 【处理子问题,得到子结果】# 【对子结果进行合并 得到最终结果】if left == right:return leftif nums.count(left) > nums.count(right):return leftelse:return right

本题分治法非最优解,但可以利用分治的思想逐步的求出众数。116ms, 15.2MB

2.排序取中间值

class Solution:def majorityElement(self, nums: List[int]) -> int:nums.sort()return nums[len(nums)//2]

中间数必为众数,44ms,15.1MB

3.哈希表

class Solution:def majorityElement(self, nums: List[int]) -> int:dict = {}for i in nums:if i in dict.keys():dict[i] +=1else:dict[i] = 1  max = 0for j in dict:if dict[j] > max:max = dict[j]index = jreturn index

第一个循环构建哈希表,字典的键为数组的值,字典的值为出现次数,第二次遍历哈希表找到最终解。56ms,15.2MB

4.摩尔投票法

class Solution:def majorityElement(self, nums: List[int]) -> int:value = 0count = 0for i in nums:if count == 0:value = iif i == value:count += 1else:count -= 1return value

摩尔投票法(Boyer–Moore majority vote algorithm),也被称作「多数投票法」,算法解决的问题是:如何在任意多的候选人中(选票无序),选出获得票数最多的那个。

算法可以分为两个阶段:

  • 对抗阶段:分属两个候选人的票数进行两两对抗抵消
  • 计数阶段:计算对抗结果中最后留下的候选人票数是否有效

在本题中,则任选一个数(第一个数)为候选者,遍历列表,不同则减一,相同加一,若总数为0,则重新选取下一个数为候选,以此类推。56ms,15MB

53.最大子序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

1.暴力计算

class Solution:def maxSubArray(self, nums: List[int]) -> int:length = len(nums)max_ = nums[0]sum_ = nums[0]for i in range(1, length):# 当当前序列加上此时的元素的值大于当前元素的值,说明最大序列和可能出现在后续序列中,记录此时的最大值if sum_ + nums[i] > nums[i]:max_ = max(max_, sum_+nums[i])sum_ = sum_ + nums[i]#当当前和小于此时加上的元素时,当前最长序列到此为止。以该元素为起点继续找最大子序列,并记录此时的最大值   else:max_ = max(max_, nums[i])sum_ = nums[i]return max_

基本思路就是遍历一遍,用两个变量,一个记录最大的和,一个记录当前的和,52ms

2.分治算法

class Solution:def maxSubArray(self, nums: List[int]) -> int:n = len(nums)#递归终止条件if n == 1:return nums[0]else:#递归计算左半边最大子序和max_left = self.maxSubArray(nums[0:len(nums) // 2])#递归计算右半边最大子序和max_right = self.maxSubArray(nums[len(nums) // 2:len(nums)])#计算中间的最大子序和,从右到左计算左边的最大子序和,从左到右计算右边的最大子序和,再相加max_l = nums[len(nums) // 2 - 1]tmp = 0for i in range(len(nums) // 2 - 1, -1, -1):tmp += nums[i]max_l = max(tmp, max_l)max_r = nums[len(nums) // 2]tmp = 0for i in range(len(nums) // 2, len(nums)):tmp += nums[i]max_r = max(tmp, max_r)#返回三个中的最大值return max(max_right,max_left,max_l+max_r)

利用分治的思想,列表的最大子序和要么在左半边,要么在右半边,要么是穿过中间,对于左右边的序列,情况也是一样,因此可以用递归处理。中间部分的则可以直接计算出来。180ms,14.3MB

3.动态规划

class Solution:def maxSubArray(self, nums: List[int]) -> int:if len(nums) == 0:return 0if len(nums) == 1:return nums[0]dp = nums[:]  # 初始化dp数组,dp[i]存储以nums[i]为结尾的子数组的和的最大值res = dp[0]for i in range(1, len(nums)):dp[i] = max(dp[i], dp[i] + dp[i - 1])  # 更新dp[i]res = max(res, dp[i]) # 更新全局最大值return res

dp[i] 存储的不是从 0 到 i 这个范围内所得到的最大的连续子数组的和,而是以 nums[i] 为结尾的子数组所能达到的最大的和。52ms,14.4MB

50. Pow(x, n)

计算 x 的 n 次幂函数。

1.分治+递归

class Solution:def myPow(self, x: float, n: int) -> float:def power(x, n):if n == 0:return 1.0temp = power(x, n//2 )if n%2 == 1:return temp*temp*xelse:return temp*tempif n>0:return power(x,n)else:return 1.0/(power(x, -n))

不断除2,需要注意的是要用一个临时变量代替递归函数,否则计算量巨大导致超时。48ms, 13.7MB

2.分治+迭代

class Solution:def myPow(self, x: float, n: int) -> float:def quickMul(N):ans = 1.0# 贡献的初始值为 xx_contribute = x# 在对 N 进行二进制拆分的同时计算答案while N > 0:if N % 2 == 1:# 如果 N 二进制表示的最低位为 1,那么需要计入贡献ans *= x_contribute# 将贡献不断地平方x_contribute *= x_contribute# 舍弃 N 二进制表示的最低位,这样我们每次只要判断最低位即可N //= 2return ansreturn quickMul(n) if n >= 0 else 1.0 / quickMul(-n)

另一个官方解法,正向计算,每当n是奇数时就单独乘一个x直到遍历结束。复杂度和上述方法一样。

本博客部分内容来源于Datawhale组对学习。

Leetcode组队学习——分治相关推荐

  1. leetcode组队学习——查找(二)

    文章目录 1.两数之和 15. 三数之和 16. 最接近的三数之和 18. 四数之和 454. 四数相加 II 49. 字母异位词分组 447. 回旋镖的数量 149. 直线上最多的点数 1.两数之和 ...

  2. leetcode组队学习——动态规划

    文章目录 主要思想 模板步骤 例题 300. 最长上升子序列 674. 最长连续递增序列 5. 最长回文子串 516. 最长回文子序列 72. 编辑距离 198. 打家劫舍 213. 打家劫舍 II ...

  3. leetcode组队学习——查找(一)

    文章目录 方法:考虑的基本数据结构 例题 202. 快乐数 205. 同构字符串 242. 有效的字母异位词 290. 单词规律 349. 两个数组的交集 350. 两个数组的交集 II 451. 根 ...

  4. 【组队学习】【31期】LeetCode 刷题

    LeetCode 刷题 航路开辟者:杨世超 领航员:刘军 航海士:杨世超.李彦鹏.叶志雄.赵子一 基本信息 开源内容:https://github.com/itcharge/LeetCode-Py 开 ...

  5. 第8期Datawhale组队学习计划

    第8期Datawhale组队学习计划马上就要开始啦 这次共组织15个组队学习,涵盖了AI领域从理论知识到动手实践的内容 按照下面给出的最完备学习路线分类,难度系数分为低.中.高三档,可以按照需要参加 ...

  6. 转发:Datawhale第七期组队学习计划

    编者注:Datawhale是一个公益组织,也是AiUnion的四个成员之一,所有学习计划是免费的. 第7期Datawhale组队学习计划 马上就要开始啦 这次共组织15个组队学习 涵盖了AI领域从理论 ...

  7. Datawhale 暑期组队学习计划

    Datawhale暑期组队学习计划 马上就要开始啦 这次共组织15个组队学习 涵盖了AI领域从理论知识到动手实践的内容 按照下面给出的最完备学习路线分类 难度系数分为低.中.高三档 可以按照需要参加 ...

  8. 第7期 Datawhale 组队学习计划

    马上就要开始啦 这次共组织15个组队学习 涵盖了AI领域从理论知识到动手实践的内容 按照下面给出的最完备学习路线分类 难度系数分为低.中.高三档 可以按照需要参加 - 学习路线 - 基础知识 01 统 ...

  9. Datawhale 三月组队学习计划

    这次一共打算组织14个组队学习,涵盖了AI领域从理论知识到动手实践的内容,难度系数分为低.中.高档,可以按照需要参加哦 组队学习信息 1 /Python基础 课程设计:马晶敏,叶梁.许辉 组队学习说明 ...

最新文章

  1. 428 Setup MySQL + - 改
  2. 源码解读_Go Map源码解读之Map迭代
  3. lync 2013 企业版部署 (四)安装office web app server
  4. 【SDL的编程】VC环境搭建
  5. java set泛型_Java 集合二 泛型、Set相关
  6. 力扣206-反转链表(Java,迭代)
  7. win定时关机_如何让电脑定时自动关机
  8. 【Flink】Flink jvm参数配置GC日志
  9. 616nyoj 新手dp
  10. 如何把手机投影到电脑,电脑可以当作电视一样被投屏
  11. 在线支付接口详解、支付接口对接
  12. pfamscan 的使用_48个在线分析使用工具
  13. html5微课程制作,翟猛老师《微课开发及制作-基于H5课件制作模式》
  14. Jenkins笔记02-Jenkins安装和持续集成环境配置
  15. pandas实现分类汇总--小计,总计
  16. android11开发版小米,小米CC9推送MIUI 12.5稳定版 新版系统内核升级至安卓11
  17. JS的map方法和Map对象
  18. DELMIA软件弧焊仿真:以工件边缘曲线为焊缝的机器人程序自动生成
  19. 二分网络上的电影推荐
  20. 团队协作出了问题,项目经理怎么办?

热门文章

  1. Python学习之路23-文本和字节序列
  2. 《LoadRunner性能测试巧匠训练营》——1.4 性能测试分类详解
  3. python 学习之 WINDOWS 注册表学习(一)
  4. Hyper-V动态扩展或差异磁盘体积缩小技巧
  5. 华为机试HJ27:查找兄弟单词
  6. wdr5600 虚拟服务器,TP-Link WDR5600路由器端口映射设置教程
  7. 自动化测试——接口测试——pandas——CSV文件参数化——数据驱动
  8. autocad支持python吗_利用python控制Autocad:pyautocad方式
  9. ubuntu16.04安装pycharm,并设置快捷启动方式
  10. linux配置sonarqube遇到的坑