搞定面试算法系列 | 分治算法三步走

戳蓝字“CSDN云计算”关注我们哦!

作者 | 江子抑

转自 | 编程拯救世界

 

主要思想

分治算法,即分而治之:把一个复杂问题分成两个或更多的相同或相似子问题,直到最后子问题可以简单地直接求解,最后将子问题的解合并为原问题的解。归并排序就是一个典型的分治算法。

在这篇文章中我们将先介绍分治算法的「三步走套路」,然后通过经典的归并排序算法体验一番分治算法的核心,最后再通过真题演练一试身手!

三步走

和把大象塞进冰箱一样,分治算法只要遵循三个步骤即可:分解 -> 解决 -> 合并

  1. 分解:分解原问题为结构相同的子问题(即寻找子问题)

  2. 解决:当分解到容易求解的边界后,进行递归求解

  3. 合并:将子问题的解合并成原问题的解


分治算法三步走

这么一说似乎还是有点抽象?那我们通过经典的排序算法归并排序来体验一下分治算法的核心思想。

归并排序

思想

归并排序的思想是:欲使序列有序,必先使其子序列有序。即先使得每个子序列有序,然后再将子序列合并成有序的列表。

因此,在归并排序中的子问题就是:使子序列有序

三步走

既然已经找到了问题的子问题,是时候套用我们上述的三步走方法了。归并排序的「三步走」如下:

  1. 分解:将序列划分为两部分

  2. 解决:递归地分别对两个子序列进行归并排序

  3. 合并:合并排序后的两个子序列

举例

来看一个具体的例子。

现在有一个待排序的序列:

10, 4, 6, 3, 8, 2, 5, 7

先对序列进行分解,把该序列一分为二,直到无法拆分为止。整个拆分过程如下:

序列分解

然后对分解出的序列进行两两排序与合并:

10, 4 排序合并后:4, 10
6, 3 排序合并后:3, 6
8, 2 排序合并后:2, 8
5, 7 排序合并后:5, 7
……

整个归并排序完整过程如下:

上部分为「分解」,下部分为「解决」与「合并」

实现

def merge_sort(lst):    # 从递归中返回长度为1的序列    if len(lst) <= 1:        return lst              middle = len(lst) / 2    # 1.分解:通过不断递归,将原始序列拆分成 n 个小序列    left = merge_sort(lst[:middle])         right = merge_sort(lst[middle:])    # 进行排序与合并    return merge(left, right)def merge(left, right):    i, j = 0, 0    result = []    # 2.解决:比较传入的两个子序列,对两个子序列进行排序    while i < len(left) and j < len(right):          if left[i] <= right[j]:            result.append(left[i])            i += 1        else:            result.append(right[j])            j += 1    # 3.合并:将排好序的子序列合并    result.extend(left[i:])             result.extend(right[j:])    return result

真题演练

为运算表达式设计优先级

LeetCode 241. 为运算表达式设计优先级: https://leetcode-cn.com/problems/different-ways-to-add-parentheses/

题目描述

给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 + , - 以及 *

示例 1:

输入: "2-1-1"输出: [0, 2]解释: ((2-1)-1) = 0 (2-(1-1)) = 2

示例 2:

输入: "2*3-4*5"输出: [-34, -14, -10, -10, 10]解释: (2*(3-(4*5))) = -34 ((2*3)-(4*5)) = -14 ((2*(3-4))*5) = -10 (2*((3-4)*5)) = -10 (((2*3)-4)*5) = 10

思路

对于一个形如 x op yop 为运算符,xy 为数) 的算式而言,它的结果组合取决于 xy 的结果组合数,而 xy 又可以写成形如 x op y 的算式。

因此,该问题的子问题就是 x op y 中的 xy以运算符分隔的左右两侧算式解

然后我们来进行分治算法三步走

  1. 分解:按运算符分成左右两部分,分别求解

  2. 解决:实现一个递归函数,输入算式,返回算式解

  3. 合并:根据运算符合并左右两部分的解,得出最终解

实现

class Solution:    def diffWaysToCompute(self, input: str) -> List[int]:        # 如果只有数字,直接返回        if input.isdigit():            return [int(input)]        res = []        for i, char in enumerate(input):            if char in ['+', '-', '*']:                # 1.分解:遇到运算符,计算左右两侧的结果集                # 2.解决:diffWaysToCompute 递归函数求出子问题的解                left = self.diffWaysToCompute(input[:i])                right = self.diffWaysToCompute(input[i+1:])                # 3.合并:根据运算符合并子问题的解                for l in left:                    for r in right:                        if char == '+':                            res.append(l + r)                        elif char == '-':                            res.append(l - r)                        else:                            res.append(l * r)        return res

总结

分治算法的核心是寻找子问题的解,解题步骤遵循「三步走」:

  1. 找到子问题并分解

  2. 解决子问题(递归)

  3. 合并子问题的解

这里为大家准备了两道练手题,大家赶紧试试手吧:

  • LeetCode 932. 漂亮数组: https://leetcode-cn.com/problems/beautiful-array

  • LeetCode 105. 从前序与中序遍历序列构造二叉树: https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

参考资料

  • OI Wiki: 递归 - 分治:https://oi-wiki.org/basic/divide-and-conquer/



福利

扫描添加小编微信,备注“姓名+公司职位”,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!

推荐阅读:

  • 扛住100亿次请求——如何做一个“有把握”的春晚红包系统

  • Windows7一个月后停止服务支持;亚马逊起诉特朗普;向量子计算商用发起挑战!英特尔发布Horse Ridge低温控制芯片……

  • 扎心!12 月全国程序员工资统计,半年工资仅涨 500 元!

  • 数学学渣必备!拍照上传,分步求解,微软解题神器拯救你

  • TIOBE 12 月编程语言排行榜:争夺年度编程语言,Java、C、Python、C# 即将开战!

真香,朕在看了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/519987.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过FD耗尽实验谈谈使用HttpClient的正确姿势

一段问题代码实验 在进行网络编程时&#xff0c;正确关闭资源是一件很重要的事。在高并发场景下&#xff0c;未正常关闭的资源数逐渐积累会导致系统资源耗尽&#xff0c;影响系统整体服务能力&#xff0c;但是这件重要的事情往往又容易被忽视。我们进行一个简单的实验&#xf…

与“十“俱进 阿里数据库运维10年演进之路

导语 阿里巴巴集团拥有超大的数据库实例规模&#xff0c;在快速发展的过程中我们在运维管理方面也在不断的面临变化&#xff0c;从物理器到容器、从独占到混布、从本地盘到存储计算分离、从集团内到大促云资源&#xff0c;从开源的MySQL到自研分布式数据库&#xff0c;运维管控…

jmeter 压测 RabbitMQ_单机

文章目录一、MQ压测1. 资料列表2. jmeter软件包3. 插件列表二、远程服务器监控2.1. 监控声明2.2. 监控场景的区别2.3. 软件列表2.4. 插件操作2.5. 软件操作三、jmeter编写MQ脚本3.1.创建线程组3.2. 创建MQ生产者3.3. 创建MQ消费者四、监听器4.1. 聚合报告4.2. 观察树4.3. 监控五…

云+X案例展 | 民生类:纷享销客助力沃得农机构筑智能化、信息化之路

本案例由纷扬科技投递并参与评选&#xff0c;CSDN云计算独家全网首发&#xff1b;更多关于【云X 案例征集】的相关信息&#xff0c;点击了解详情丨挖掘展现更多优秀案例&#xff0c;为不同行业领域带来启迪&#xff0c;进而推动整个“云行业”的健康发展。​​​​“2004年到20…

如何“神还原”数据中心? 阿里联合NTU打造了工业级精度的仿真沙盘!

如何保障数据中心的稳定运行&#xff0c;是多年来一直困扰业界的难题。机房环境如果发生未预期变化&#xff0c;可能造成难以估计的损失。所以我们希望能构建一个“变更沙盘”&#xff0c;在真实变更之前&#xff0c;操作人员可以先在沙盘中进行试变更&#xff0c;若变更效果在…

RabbitMQ 手动签收

下面这基础地方都必须设置&#xff0c;不然无效 // 同一时刻服务器只会发一条消息给消费者channel.basicQos(1); // 消息的标识&#xff0c;false只确认当前一个消息收到&#xff0c;true确认所有consumer获得的消息 channel.basicAck(message.getMessageProperties().getDeli…

把16进制转换为ascii字符c语言,ASCII转16进制C语言

满意答案u2gseftj278推荐于 2016.03.01采纳率&#xff1a;56% 等级&#xff1a;11已帮助&#xff1a;14340人以前引别人的&#xff0c;自己懒得再写了呵呵。原理就是这样的&#xff0c;你可以直接用的//函 数 名&#xff1a;AscToHex()//功能描述&#xff1a;把ASCII转换为1…

四大维度全景揭秘阿里巴巴智能对话开发平台

在阿里巴巴智能服务事业部的X蜂会上&#xff0c;小蜜北京团队的高级算法专家李永彬&#xff08;水德&#xff09;分享了小蜜智能对话开发平台的构建&#xff0c;围绕平台来源、设计理念、核心技术、业务落地情况四大维度讲述了一个较为完整的智能任务型对话开发平台的全景。以下…

2019年技术盘点云数据库篇(二):阿里云携手MongoDB率先上线4.2数据库 云上数据库已是大势所趋...

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 刘丹出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;随着技术的飞速发展&#xff0c;云数据库在云计算的大背景下&#xff0c;作为一种新兴的共享基础架构方法逐渐发展起来&#xff0c;它极大地增强了数据…

Oracle 查看表空间的大小及使用情况sql语句

SELECT a.tablespace_name "表空间名称", total / (1024 * 1024) "表空间大小(M)", free / (1024 * 1024) "表空间剩余大小(M)", (total - free) / (1024 * 1024 ) "表空间使用大小(M)", total / (1024 * 1024 * 1024) "表空…

高可用、弹性动态的金融级移动架构在蚂蚁金服的演进之路

本文基于重岳在 2018 年 Arch Summit 北京站的分享内容进行总结&#xff0c;希望通过本篇文章介绍近些年来支付宝在移动端架构的上演进和思考&#xff0c;期冀能给读者们带来些许帮助。 支付宝作为国民级应用&#xff0c;当前全球用户已经超过 10 亿&#xff0c;提供了超过 200…

Android代码混淆方法,Android 代码混淆零基础入门

内容提要本篇文章主要有三个部分&#xff0c;让读者读完后能自己写规则混淆项目对Android代码怎么开启混淆做一个简单的介绍。对混淆规则做一个简单介绍&#xff1b;在混淆过后Crash日志反推代码工具retrace.bat、可视化反推工具GUI说明。对混淆的一个简单介绍&#xff1a;Andr…

oracle查询当前用户名下所有表

--SONARQUBE为用户名&#xff0c;用户名必须是大写 SELECT * from all_tables where ownerSONARQUBE;--查看当前登录的用户的表: SELECT table_name from user_tables;

JUC包中的分而治之策略-为提高性能而生

一、前言 本次分享我们来共同探讨JUC包中一些有意思的类&#xff0c;包含AtomicLong & LongAdder,ThreadLocalRandom原理。 二、AtomicLong & LongAdder 2.1 AtomicLong 类 AtomicLong是JUC包提供的原子性操作类&#xff0c;其内部通过CAS保证了对计数的原子性更新…

galaxy s8 android pc,手机秒变PC!三星Galaxy S8桌面模式曝光

据外媒报道&#xff0c;三星旗舰手机Galaxy S8/S8 Plus在外观上以及硬件配置上已经没有了悬念。不过一些小的改进或者是新功能还是让人对Galaxy S8充满期待。日前&#xff0c;传闻中的Galaxy S8桌面模式终于被曝光。三星Galaxy S8桌面模式曝光(图片来自kkj)报道称&#xff0c;G…

2020年进军 AI,想年薪 40 万,没这个能力不行

前几天&#xff0c;《百度沸点&#xff1a;2019年度科技热词》来了&#xff01;百度沸点&#xff1a;2019年度科技热词 AI排名第一2019年可以说是AI全面落地和商用的一年&#xff0c;产业智能化成为各个行业重点关注的发展方向&#xff0c;交通、工业、农业、医疗等主流行业无一…

重磅公开!阿里语音识别模型端核心技术,让你“听”见未来

语音识别技术作为人工智能技术中的重要组成部分&#xff0c;成为影响人机交互的核心组件之一&#xff0c;从各种智能家用IoT设备的语音交互能力&#xff0c;到公共服务、智慧政务等场合的应用&#xff0c;语音识别技术正在影响着人们生活的方方面面。 本文将全面介绍阿里云语音…

linux搭建SonarQube代码质量平台_Oracle 最新详细版本

文章目录一、最低配置要求1. JDK版本要求2. 数据库版本要求3. 支持浏览器版本二、软件下载安装2.1. 软件列表总览2.2. jdk11下载2.3. sonarqube下载2.4. sonar-scanner-cli2.5. Oracle 驱动三、安装实战3.1. JDK sonar-scanner3.2. sonarqube3.3. oracle驱动3.4. 启动sonar3.4.…

2018年AI和ML(NLP、计算机视觉、强化学习)技术总结和2019年趋势(上)

1、简介&#xff1a; 过去几年一直是人工智能爱好者和机器学习专业人士最幸福的时光。因为这些技术已经发展成为主流&#xff0c;并且正在影响着数百万人的生活。各国现在都有专门的人工智能规划和预算&#xff0c;以确保在这场比赛中保持优势。 数据科学从业人员也是如此&am…

2018最佳GAN论文回顾(下)

继上一篇《2018最佳GAN论文回顾&#xff08;上&#xff09;》&#xff0c;我又继续介绍了一个对于GAN的基于样式的生成器体系结构的新论文&#xff0c;提出了一个新的模型来应对这种挑战。 一种用于生成式对抗网络的基于生成器体系结构的方式&#xff08;A Style-Based Genera…