labuladong 的算法小抄_来自GitHub 68.8k star的硬核算法教程

5af757de0a12cf88024c02d30767af62.png

很多朋友害怕算法,其实大可不必,算法题无非就那几个套路,一旦掌握,就会觉得算法实在是太朴实无华且枯燥了!

本文选自硬核算法教程《labuladong的算法小抄》,带你学习套路,把握各类算法问题的共性!

数据结构是工具,算法是通过合适的工具解决特定问题的方法。对于任何数据结构,其基本操作无非遍历 + 访问,再具体一点就是:增、删、查、改。

那么该如何在力扣刷题呢?很多文章都会告诉你“按标签刷”“坚持下去”等。不说这些不痛不痒的话,直接给具体的建议。

先刷二叉树

先刷二叉树

!!先刷二叉树!!

这是我刷题一年的亲身体会,下图是 2019 年 10 月的提交截图:

e3662a6a9b2efab814cc1150557064a0.png

据我观察,大部分人对与数据结构相关的算法文章不感兴趣,而是更关心动态规划、回溯、分治等技巧。这是不对的,这些常考算法技巧在《labuladong的算法小抄》中都会有所涉及,到时候你就会发现,它们看起来高大上,但本质上就是一个多叉树遍历的问题,配合算法框架,并没有多难。

  • 为什么要先刷二叉树呢?

因为二叉树是最容易培养框架思维的,而且大部分常考算法本质上都是树的遍历问题。

  • 刷二叉树时看到题目没思路?

其实大家不是没思路,只是没有理解“框架”是什么。不要小看下面这几行代码,几乎所有二叉树的题目一套用这个框架就都出来了。

1void traverse(TreeNode root) {2    // 前序遍历3    traverse(root.left);4    // 中序遍历5    traverse(root.right);6    // 后序遍历7}

比如随便拿几道题的解法代码出来,这里不用管具体的代码逻辑,只看看框架在其中是如何发挥作用的。

LeetCode 124 题 ,难度为 Hard,求二叉树中最大路径和,主要代码如下:

 1int ans = INT_MIN; 2int oneSideMax(TreeNode* root) { 3    if (root == nullptr) return 0; 4 5    int left = max(0, oneSideMax(root->left)); 6    int right = max(0, oneSideMax(root->right)); 7 8    /**** 后序遍历 ****/ 9    ans = max(ans, left + right + root->val);10    return max(left, right) + root->val;11    /****************/12}

你看,这不就是后序遍历嘛。

那为什么是后序呢?题目要求最大路径和,对于一个二叉树节点,是不是先计算左子树和右子树的最大路径和,然后加上自己的值,这样就得出新的最大路径和了?所以说这里就要使用后续遍历框架。

LeetCode 105 题 ,难度为 Medi um,要求根据前序遍历和中序遍历的结果还原一棵二叉树,这是很经典的问题,主要代码如下:

 1TreeNode buildTree(int[] preorder, int preStart, int preEnd,  2    int[] inorder, int inStart, int inEnd, Map inMap) { 3 4    if(preStart > preEnd || inStart > inEnd) return null; 5 6    /**** 前序遍历 ****/ 7    TreeNode root = new TreeNode(preorder[preStart]); 8    int inRoot = inMap.get(root.val); 9    int numsLeft = inRoot - inStart;10    /****************/1112    root.left = buildTree(preorder, preStart + 1, preStart + numsLeft, 13                          inorder, inStart, inRoot - 1, inMap);14    root.right = buildTree(preorder, preStart + numsLeft + 1, preEnd, 15                          inorder, inRoot + 1, inEnd, inMap);16    return root;17}

不要看这个函数的参数很多,它们只是为了控制数组索引而已,本质上该算法就是一个前序遍历算法。

LeetCode 99 题 ,难度为 Hard,要求恢复一棵 BST(完全二叉树),主要代码如下:

 1void traverse(TreeNode* node) { 2    if (!node) return; 3 4    traverse(node->left); 5 6    /****中序遍历 ****/ 7    if (node->val val) { 8        s = (s == NULL) ? prev : s; 9        t = node;10    }11    prev = node;12    /****************/1314    traverse(node->right);15}

这不就是中序遍历嘛,对于一棵 BST,中序遍历意味着什么,应该不需要解释了吧。

你看,Hard 难度的题目不过如此,而且还这么有规律可循,只要把框架写出来,然后往相应的位置加内容就行了,这不就是思路嘛!

对于一个理解二叉树的人来说,刷一道二叉树的题目花不了多长时间。那么如果你对刷题无从下手或者有畏惧心理,不妨从二叉树下手,前 10 道也许有点难受;结合框架再做 20 道题,也许你就有点自己的理解了;刷完整个专题,再去做什么回溯、动态规化、分治专题,你就会发现只要涉及递归的问题,基本上都是树的问题。

▽▽▽

再举些例子吧。

在《labuladong的算法小抄》“动态规划解题套路框架”章节中,会讲到凑零钱问题,暴力解法就是遍历一棵 N 叉树:

 1def coinChange(coins: List[int], amount: int): 2 3    def dp(n): 4        if n == 0: return 0 5        if n 

这么多代码看不懂怎么办?直接提取框架,这样就能看出核心思路了,这就是刚才说到的遍历 N 叉树的框架:

1def dp(n):2    for coin in coins:3        dp(n - coin)
c9a144bf55fe55f4b52be97547fcfca1.png

其实很多动态规划问题就是在遍历一棵树,你如果对树的遍历操作烂熟于心,那么起码知道怎么把思路转化成代码,也知道如何提取别人解法的核心思路。

再看看回溯算法,在《labuladong的算法小抄》“回溯算法解题套路框架”中会直接告诉你,回溯算法就是一个 N 叉树的前序 + 后序遍历问题,没有例外。比如,排列组合问题、经典的回溯问题,主要代码如下:

 1void backtrack(int[] nums, LinkedList track) { 2    if (track.size() == nums.length) { 3        res.add(new LinkedList(track)); 4        return; 5    } 6 7    for (int i = 0; i  track) {18    for (int i = 0; i 

N 叉树的遍历框架,找出来了吧。你说,树这种结构重不重要?

综上所述,对于畏惧算法或者刷题很多但依然感觉不得要领的朋友来说,可以先刷树的相关题目,试着从框架看问题,而不要纠结于细节。

所谓纠结细节,就比如纠结 i 到底应该加到 n 还是加到 n - 1 ,这个数组的大小到底应该开成 n 还是 n + 1 ?

从框架看问题,就是像我们这样基于框架进行抽取和扩展,既可以在看别人解法时快速理解核心逻辑,也有助于我们找到自己写解法时的思路方向。

当然,如果细节出错,你将得不到正确的答案,但是只要有框架,再错也错不到哪去,因为你的方向是对的。但是,你要是心中没有框架,那么根本无法解题,给你答案,也不能意识到这就是树的遍历问题。

框架思维是很重要的,有时候按照流程写出解法,说实话我自己都不知道为啥是对的,反正它就是对了……

这就是框架的力量,能够保证你在思路不那么清晰的时候,依然写出正确的程序。

—— ——

最后我们总结一下,刷算法题建议从“树”分类开始刷,结合框架思维,把几十道题刷完,对于树结构的理解应该就到位了。这时候去看回溯、动态规划、分治等算法专题,对思路的理解可能会更加深刻一些。

在思考问题的过程中,少纠结细节,不要热衷于炫技;希望读者多从框架看问题,多学习套路,把握各类算法问题的共性,《labuladong的算法小抄》将会为你提供这方面的帮助。

图书推荐

4a4203b97f1b4bdc7a95d5b235b35891.png

▊《labuladong的算法小抄》

付东来(@labuladong) 著

  • GitHub 68.8k star的硬核算法教程
  • labuladong带你挑战力扣算法题
  • 挑战BAT等大厂Offer

本书专攻算法刷题,训练算法思维,应对算法笔试。注重用套路和框架思维解决问题,以不变应万变。

12f4318e7336bcea50d1f72de665e97a.png

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

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

相关文章

router vue 动态改变url_2020年 vue常见面试问题总结(干货)!

1.什么是mvvm模式,谈谈你的理解? MVVM - Model View ViewModel,数据,视图,视图模型view 可以通过 事件绑定 的方式影响 model,model 可以通过 数据绑定 的形式影响到view,viewModel是把 model 和…

html怎么弄艺术字体,如何为图片加上艺术字的图文方法步骤

给图片加字有好多方法,比如用photoshop等专业工具,在线图片加字,但是前者效果好,操作较复杂,后者效果不大理想。其实有更简单相对效果也不错的方法,利用你手边的工具就可以了!下面介绍利用Windo…

androidstudio调用系统相机为什么resultcode一直返回0_函数递归调用?看这文就够了...

作者 | Cooper Song责编 | Elle出品 | 程序人生(ID:coder_life)我猜,大多数程序员第一次接触函数的递归调用都是在算斐波那契数列某项值的时候,这是函数递归调用最常见的应用之一。规定第一项和第二项为1,后面的项,每一…

http请求 url 竖线_http.createServer创建http服务

语法:http.createServer([options][, requestListener])第二个参数requestListener,是一个自动添加到request事件的方法。返回一个新的 http.Server实例。之前代码是使用server.on(request,callback)来监听请求事件,由于http.createServer第二…

物理不突出能学计算机吗,物理成绩不突出,高中选科怎么办?3个理由让你解除后顾之忧!...

目前确定将要于2021年采用新高考“312”模式的有河北、辽宁、江苏、福建、湖南、湖北、广东和重庆8个省市。但是很多高一新生和家长们,面对选科问题时,却是犯了愁。“想选物理呢,物理成绩不突出,没有优势,听说选考物理…

@bean注解和@component注解的区别_通过源码查看 @Component,@Service 等注解是如何被解析的...

点击上方“匠心零度”,选择“设为星标”做积极的人,而不是积极废人来源:my.oschina.net/floor/blog/4325651前言1.Component解析流程找入口找核心方法概要分析2.查文档找思路3. 探寻Component派生性流程1. 确定metadataReader2.查看match方法…

centos7已有数据硬盘挂载_干货!如何给虚拟机增加虚拟硬盘,Linux再分区挂载

很多朋友一开始给虚拟机的硬盘都很小,用着用着虚拟硬盘就不够了,今天小编就给大伙说说如何给虚拟机添加虚拟硬盘在到Linux系统下分区格式化再到挂载。点击创建新的虚拟盘我分配一个8g的硬盘吧!现在启动centos 7查看一下你刚刚添加的8G的硬盘&…

diy机器人图片 手绘纸箱_废物利用,她用几个纸箱让家里变成动物园,孩子回家乐坏了!收藏...

纸箱是我们日常生活中最常见的一种废品,现在随着网购的崛起,家里的纸箱越来越多,这时候你是直接丢弃,还是会想想是否可以再利用的价值?这些看似没用的纸箱,在创意妈的眼中可是个宝贝呢~它可以变废为宝成为孩…

计算机研究生考426分单科多少,考研初试426分,依然没被录取,他犯的错误,值得大家参考!...

原标题:考研初试426分,依然没被录取,他犯的错误,值得大家参考!最近几天,考研初试成绩陆续发布。考试分数比较高的考生,有机会参加复试,就要尽早准备复试复习了。复试成绩也很重要&am…

70进货卖100利润是多少_一只周黑鸭随便就卖100多,那成本有多少?说出来你可能不信...

一只周黑鸭动不动就卖100多,那成本有多少?说出来你可能不信。如果你吃过周黑鸭,不知道每次想起的时候,尤其是午夜时分会不会有流口水的感觉,那种麻辣的口感,再搭配上冰凉爽口的啤酒,发自心底的那…

powerquery加载pdf_pdf转换为excel,你不会,同事点点鼠标2分钟就搞定了

Hello.大家好,最近office365进行了一次小的更新,这次更新在excel中添加了获取pdf文件中的表格的功能,操作起来十分的简单,下面就跟大家分享下它是如何操作的首先我们新建一个excel文件,然后点击数据功能组,…

防火墙设置导致服务器站点打开,服务器、网站、环境配置全正常网站打不开原来是系统防火墙造成的...

大家都知道网站是架在服务器上的,通过域名解析指向网站并在服务器上绑定域名,上传网站程序到指定的目录,并只要有适合网站运行的环境,网站目录权限正常网站就肯定可以正常运行了,但今天我们技术遇到了一个问题以上所说…

web前端开发技术期末考试_智慧树来我校开展WEB前端开发微专业导学

11月17日,在6号教学楼6102阶梯教室,智慧树工作人员带来了WEB前端开发微专业导学。根据前期长青联盟微专业的报名情况及学生学习情况,为进一步提高学生学习微专业的质量,学院联系了微专业教学平台的专家对教学平台的使用进行技术指…

计算机辅助设计还需要手绘吗,西安电脑如此发达为什么还要学习手绘

在处理器以八核成为主流、硬盘以T而论的今天,计算机辅助设计软件是设计师的得力工具。用铅笔、尺子要时间才能画好的一个室内空间平面布置图,如果用CAD可能一个小时都不用就完成了,而且很方便修改,可见在效率方面,电脑…

一键生成通讯录的软件_橙瓜码字自动写作软件,外貌描写对话描写一键生成

很多写手对于以古代为背景的小说,偶尔都会对某些地方感到棘手,有时候是历史的背景,有时候是当时的官制、称呼,或是一些特有的服饰,外貌的描写,而面对难题,很多时候我们也是选择上网查询&#xf…

gin 静态文件服务器拒绝,nginx实现简单的图片服务器(windows)+静态文件服务器-Go语言中文社区...

需求:能够使用 http://localhost/目录/图片名 访问本地(服务器)已经存在的图片首先需要在本地将nginx跑起来,这里使用默认端口80;在浏览器使用http://localhost看到下面的界面证明nginx启动正常。下面需要修改nginx.conf来实现直接使用http:/…

wegame每次登陆都要滑动验证_Vue项目中实现用户登录及token验证

在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下:1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个toke…

云服务器 性能监控软件,云监控 - 云应用监控 - ManageEngine Applications Manager

云监控什么是云监控?尽管许多组织仍然依赖于在自托管的数据中心中存储数据的本地方法,但在业务组织中采用云服务的情况已经逐渐增多。自然,这导致了一些云监控工具的出现。无论您使用的是公共、私有还是混合环境,对应用程序性能具有端到端可…

mysql导入dat文件_MySql导入和抽取大数量级文件数据

一、情况介绍需要处理的文件是一个3.41G的csv格式文件,现在需要把它导入数据库,进行后续处理和分析。二、导入数据该文件数据量庞大,无法用excel或者editplus之类普通软件打开,于是借用了pandas的方法查看了表的结构:方…

服务器操作系统与安装步骤,服务器操作系统与安装步骤

服务器操作系统与安装步骤 内容精选换一换如果在创建弹性云服务器时未设置密码,或密码丢失、过期,可以参见本节操作重置密码。密码丢失或过期前,已安装密码重置插件。公共镜像创建的弹性云服务器默认已安装一键重置密码插件。私有镜像创建的云…