
算法之美与力扣实战
文章平均质量分 92
从LeetCode实践的角度出发,深入探讨算法设计与数据结构背后的原理。本系列文章,不仅分享LeetCode经典例题的解题思路(配有大量图示辅助理解)和解题套路,同时循序渐进地讲解了动规、回溯、二分、哈希、DFS等算法设计方面的知识点
白马负金羁
数据挖掘 | 统计分析 | 图像处理 | 程序设计
展开
-
算法之美隆重上市欢迎关注(另附勘误表在此)
探秘算法世界,求索数据结构之道;汇集经典问题,畅享编程技法之趣;点拨求职热点,敲开业界名企之门。本书围绕算法与数据结构这个话题,循序渐进、深入浅出地介绍了现代计算机技术中常用的四十余个经典...原创 2016-01-12 12:31:48 · 15374 阅读 · 53 评论 -
深入理解二叉索引树:从LeetCode实践出发(题号307、315、327、493)
Fenwick Tree也叫做树状数组,或者二叉索引树(BIT,Binary Indexed Tree),由新西兰奥克兰大学的Peter Fenwick博士于1994年提出。Fenwick Tree用数组来表示一棵树(这样空间上更节约),所以它的结点中没有指向左右孩子的指针这样的设计。它可以用于对区间和(range sum)进行快速查询,其元素修改和区间查询的复杂度都是O(logn)。LeetCode上会用到Fenwick Tree的题目只要十几道,但是基本都是Hard级别的难题原创 2021-06-10 07:57:40 · 419 阅读 · 0 评论 -
算法之美与力扣实战专栏详解:订阅前必读
本专栏从LeetCode实践的角度出发,深入探讨算法设计与数据结构背后的原理。笔者希望透过本系列文章,不仅分享LeetCode经典例题的解题思路(配有大量图示辅助理解)和解题套路,同时循序渐进地讲解了动规、回溯、二分、哈希、DFS等算法设计方面的知识点。本专栏的终极目标是希望你能够在一个固定的地方,找到所需的、所有的、高质量的LeetCode题目解析原创 2021-05-26 10:41:08 · 1235 阅读 · 1 评论 -
深入理解数学计算问题:从LeetCode实践出发【1】(题号50、69、231、204、504)
计算机(正如其名字所展现的那样)最初的用途就是进行科学计算。跟数学(或计算)相关的问题也广泛存在于LeetCode题库之中。这种类型的题目,虽然可以归为一类,但具体解法却是各式各样的,很多会涉及到数学上的一些技巧和成熟的算法。本文将攫取若干比较有代表性的LeetCode题目来展示如何在实践中对该类型问题进行求解原创 2009-08-27 08:33:00 · 5706 阅读 · 12 评论 -
深入理解数学计算问题:从LeetCode实践出发【2】(题号31、60、89、48、292)
本文是深入理解数学计算问题的第二篇。这些LeetCode题目涉及到一些数学算法,但更具体地讲,每道题目又各自为政,即不存在某种普遍的算法可以用来解决下面这些问题。如果你不知道、不了解具体问题的具体算法,下面的任何一个问题都可能在面试的时候把你难倒。我把符合这种特点的题目搜罗到这篇文章中,希望给它们来个一网打尽原创 2016-01-07 20:03:41 · 7858 阅读 · 2 评论 -
深入理解数学计算问题:从LeetCode实践出发【3】(题号166、279)
本文是深入理解数学计算问题的第三篇。这些跟数学有关的编程题目的特点是,要么借助常规算法(例如动态规划)可以解决,要么在非常直接的数学算法实现中需要使用一些数据结构方面的基本知识(例如哈希)。因此,这些题目也比较具有代表性。与仅仅考察一些特殊的数学知识相比,它们其实更有意义原创 2021-06-05 11:35:53 · 272 阅读 · 0 评论 -
深入理解随机算法:从LeetCode实践出发【1】(题号380、381、398、528)
随机算法在计算机科学中有重要应用。常说的蒙特卡洛算法或拉斯维加斯算法都属于是随机算法。随机算法或与之相关的数据结构,会要求操作在一定概率下随机返回结果(或者随机执行),例如随机删除、随机访问等。这类题目,难度通常不大,主要应试者要熟悉语言的内置随机数生成方法。当然,如果有Follow up要求的话,一般需要在一定的时间复杂度下实现算法,那么此时会有一定挑战原创 2021-05-20 03:07:18 · 310 阅读 · 0 评论 -
深入理解随机算法:从LeetCode实践出发【2】(题号478、470、382、710)
随机算法在计算机科学中有重要应用。常说的蒙特卡洛算法或拉斯维加斯算法都属于是随机算法。随机算法或与之相关的数据结构,会要求操作在一定概率下随机返回结果(或者随机执行),例如随机删除、随机访问等。而且,如果有Follow up要求的话,一般需要在一定的时间复杂度下实现算法,这会给求解带来挑战。本文将从LeetCode题目中筛选出一些非常具有代表性的题目,它们的共同特点在于需要用到一些特殊的算法(Reject Sampling、蓄水池采样等)来演示此类问题的解法原创 2021-05-20 07:00:55 · 336 阅读 · 0 评论 -
深入理解结构设计与实现:从Leetcode实践出发【1】(题号225、232、155、716、706)
高级程序设计语言中通常都已经提供了许多常用的数据结构实现(例如Python中的collection,或者C++中的STL)。LeetCode中广泛存在的'Design'类型题目往往会要求应试者在不使用内置函数库的情况下,自行实现某个数据结构(有时还是有特殊要求的数据结构)。这类题目更多考察的往往是面向对象程序设计(尤其是使用某种语言进行面向对象编程)的能力(算法方面的考察则往往不多)。本文将挑选若干具有代表性的LeetCode题目,演示此类题目的求解思路原创 2021-05-20 01:29:12 · 274 阅读 · 0 评论 -
深入理解结构设计与实现:从Leetcode实践出发【2】(题号341、339、364、1381、1188)
高级程序设计语言中通常都已经提供了许多常用的数据结构实现(例如Python中的collection,或者C++中的STL)。LeetCode中广泛存在一种分类标签为'Design'类型的题目。它们往往会要求应试者在不使用内置函数库的情况下,自行实现某个数据结构(有时还是有特殊要求的数据结构)。这类题目更多考察的往往是面向对象程序设计(尤其是使用某种语言进行面向对象编程)的能力(算法方面的考察则往往不多原创 2021-05-22 05:14:55 · 302 阅读 · 4 评论 -
深入理解二叉树与递归:从LeetCode实践出发【1】(题号1448、129、617、814、98、333、124)
递归是强大的问题求解工具,是程序设计中的一种重要思想和机制。递归有助于写出清晰易懂的代码,能有效提高程序的整体风格。此外,很多算法的实现都有赖于递归函数,例如DFS、回溯、动态规划等。二叉树是一种典型的递归数据结构。因此,很多跟二叉树有关的问题用递归的代码来求解都是最方便的。本文主要以LeetCode中的题目为例,演示利用递归的方法解决二叉树有关问题的技巧与方法原创 2021-04-12 08:54:10 · 761 阅读 · 1 评论 -
深入理解二叉树与递归:从LeetCode实践出发【2】(题号235、236、1026、1123、1650)
递归是强大的问题求解工具,是程序设计中的一种重要思想和机制。递归有助于写出清晰易懂的代码,能有效提高程序的整体风格。此外,很多算法的实现都有赖于递归函数,例如DFS、回溯、动态规划等。二叉树是一种典型的递归数据结构。因此,很多跟二叉树有关的问题用递归的代码来求解都是最方便的原创 2021-04-12 12:20:54 · 440 阅读 · 1 评论 -
深入理解二叉树与递归:从LeetCode实践出发【3】(题号114、297、449、1008、450)
递归是强大的问题求解工具,是程序设计中的一种重要思想和机制。递归有助于写出清晰易懂的代码,能有效提高程序的整体风格。此外,很多算法的实现都有赖于递归函数,例如DFS、回溯、动态规划等。二叉树是一种典型的递归数据结构。因此,很多跟二叉树有关的问题用递归的代码来求解都是最方便的。本文是系列文章的第3篇,并将继续以LeetCode中的题目为例,演示利用递归的方法解决二叉树有关问题的技巧与方法原创 2013-09-14 14:03:08 · 9945 阅读 · 3 评论 -
深入理解二叉树与递归:从LeetCode实践出发【4】(题号655、662、669、105、106)
递归是强大的问题求解工具,是程序设计中的一种重要思想和机制。递归有助于写出清晰易懂的代码,能有效提高程序的整体风格。此外,很多算法的实现都有赖于递归函数,例如DFS、回溯、动态规划等。二叉树是一种典型的递归数据结构。因此,很多跟二叉树有关的问题用递归的代码来求解都是最方便的。本文是系列文章的最终弹,精心挑选了LeetCode中极具代表性的题目,演示利用递归的方法解决二叉树有关问题的技巧与方法原创 2015-11-14 12:42:28 · 3990 阅读 · 1 评论 -
深入理解二叉树与递归:从LeetCode实践出发【5】(题号95、116、117、255、536)
递归是强大的问题求解工具,是程序设计中的一种重要思想和机制。递归有助于写出清晰易懂的代码,能有效提高程序的整体风格。此外,很多算法的实现都有赖于递归函数,例如DFS、回溯、动态规划等。二叉树是一种典型的递归数据结构。因此,很多跟二叉树有关的问题用递归的代码来求解都是最方便的原创 2015-11-12 13:26:17 · 5132 阅读 · 0 评论 -
深入理解优先队列与堆:从Leetcode实践出发【1】(题号253、670、146、767)
在实际应用中,队列中的元素可能需要一定的优先级,每次从队列中取出具有特定优先级的元素。这种队列叫做优先级队列(Priority Queue)。实现优先级队列的方法有很多种,使用堆(Heap)来实现是一种比较常见且高效的方法。Python中对优先级队列和堆,都提供了很好的支持。LeetCode题库中有相当一部分会考察堆的使用与理解,本文将从LeetCode实战的角度出发,演示堆(或优先级队列)在问题求解中的具体应用原创 2021-04-08 12:14:41 · 656 阅读 · 13 评论 -
深入理解优先队列与堆:从Leetcode实践出发【2】(题号23、215、857、295)
堆是一种非常有用的数据结构类型,它可以用作执行优先级队列的存储结构,也可以用来实现堆排序。Python中对优先级队列和堆,都提供了很好的支持。LeetCode题库中有相当一部分会考察堆的使用与理解,本文将从LeetCode实战的角度出发,演示堆(或优先级队列)在问题求解中的具体应用原创 2021-04-08 17:46:03 · 491 阅读 · 0 评论 -
深入理解并查集:从Leetcode实践出发【1】(题号547、323、721)
不相交集(Disjoint Set)又称并查集,是解决等价或划分问题的一种有效的数据结构(树和森林常常被用来描述不相交集)。本文主要节选《算法之美:隐匿在数据结构背后的原理》一书中的相关章节来介绍并查集的基本原理和操作,此处会采用Python3重新实现相关算法。同时,本文还将以一道LeetCode题目为例来具体说明如何利用并查集这种特殊的数据结构解决实际问题原创 2021-03-27 09:32:00 · 301 阅读 · 0 评论 -
深入理解并查集:从Leetcode实践出发【2】(题号924、990、684、261)
不相交集(Disjoint Set)又称并查集,是解决等价或划分问题的一种有效的数据结构(树和森林常常被用来描述不相交集)。前一篇文章已经介绍了关于这种特殊数据结构的基本知识,并采用Python3实现了并查集类。本文将继续以LeetCode题目为例来具体实践如何利用并查集这种特殊的数据结构解决实际问题原创 2021-03-29 19:36:09 · 512 阅读 · 3 评论 -
深入理解二分查找:从LeetCode实践出发【1】(题号34、35)
二分查找是数据结构与算法课程中应该讲到的一个非常重要的内容。通常,二分查找算法可以通过迭代来实现,也可以借由递归的结构来实现。但是在实际应用中二分查找可能变化出许多更为复杂的形式原创 2009-10-19 14:12:00 · 3650 阅读 · 31 评论 -
深入理解二分查找:从LeetCode实践出发【2】(题号875、658、29、240、436、378)
二分查找(Binary Search)是数据结构与算法课程中应该讲到的一个非常重要的内容。通常,二分查找算法可以借由递归的结构来实现,也可以通过迭代来实现。但是在实际应用中二分查找可能变化出许多更为复杂的形式,面对这些变种题目时能否得心应手地来处理,便考察了你是否真正掌握了二分查找的精髓原创 2021-03-12 14:55:22 · 325 阅读 · 0 评论 -
深入理解栈结构:从Leetcode实践出发【1】(题号20、32、1249、150、735)
栈是一种非常重要的线性数据结构,它的特点在于最后入栈的数据项也将是最先被处理的数据项。Leetcode中涉及很多与栈相关的题目,而且可以基于栈实现的DFS(也包括回溯法)相关的题目在Leetcode中更是非常普遍。牢固掌握栈的使用,并攻克相关类型题目也非常重要。本文将基于Leetcode中的题目来实际展示一下栈的使用原创 2021-03-10 06:06:43 · 294 阅读 · 0 评论 -
深入理解栈结构:从Leetcode实践出发【2】(题号901、496、739、503、84、85、42)
栈是一种非常重要的线性数据结构,它的特点在于最后入栈的数据项也将是最先被处理的数据项。Leetcode中涉及很多与栈相关的题目。此外,像树的深度遍历除了使用递归以外,另外一种写法就是利用栈来迭代(循环)实现。而DFS(也包括回溯法)相关的题目在Leetcode中更是非常普遍。因此,牢固掌握栈的使用,并攻克相关类型题目也非常重要原创 2021-03-10 07:48:57 · 353 阅读 · 0 评论 -
深入理解栈结构:从Leetcode实践出发【3】(题号20、32、301)(括号匹配问题)
括号匹配问题是用“栈”这种数据结构来解决的一道典型问题,本文由此引申,谈到了Leetcode中多道与此有关的问题或变种题,这是笔试面试中非常常见的一种类型题目原创 2016-01-05 23:24:53 · 11049 阅读 · 1 评论 -
深入理解栈结构:从Leetcode实践出发【4】(题号150)(逆波兰表达式)
逆波兰表示法(RPN,Reverse Polish Notation),是一种是由波兰逻辑学家与哲学家扬·武卡谢维奇(Jan Łukasiewicz)1920年引入的数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法原创 2009-07-29 01:59:00 · 2468 阅读 · 7 评论 -
深入理解深度优先搜索:从Leetcode实践出发【1】(题号94、144、145、104、230)
在树(或者图)中进行搜索是一个非常重要的话题,具体来说,又分为深度优先搜索(DFS,Depth First Search)和广度优先搜索(BFS, Breadth First Search)两种。其中,前者的理解难度要大于后者,而且在Leetcode解题中,前者应用得也更多。在涉及到回溯或动态规划时,往往也需要借助到DFS来编程实现。本文将从Leetcode题目求解的角度出发,通过实践来探讨一下DFS有关的一些话题原创 2021-02-07 09:19:47 · 415 阅读 · 0 评论 -
深入理解深度优先搜索:从Leetcode实践出发【2】(题号733、559、695、200、690、17)
在树(或者图)中进行搜索是一个非常重要的话题,具体来说,又分为深度优先搜索(DFS,Depth First Search)和广度优先搜索(BFS, Breadth First Search)两种。其中,前者的理解难度要大于后者,而且在Leetcode解题中,前者应用得也更多。在涉及到回溯或动态规划时,往往也需要借助到DFS来编程实现原创 2021-03-06 04:45:13 · 526 阅读 · 1 评论 -
深入理解深度优先搜索:从Leetcode实践出发【3】(题号785、207、797、802、1319)
在图中进行搜索是一个非常重要的话题,具体来说,又分为深度优先搜索(DFS,Depth First Search)和广度优先搜索(BFS, Breadth First Search)两种。其中,前者的理解难度要大于后者,而且在Leetcode解题中,前者应用得也更多。在涉及到回溯或动态规划时,往往也需要借助到DFS来编程实现。本文将从Leetcode题目求解的角度出发,通过实践来探讨一下DFS有关的一些话题原创 2021-03-06 17:53:50 · 965 阅读 · 5 评论 -
深入理解回溯法:从Leetcode实践出发【1】(题号46、47、78、90、784)
回溯法(Backtracking)是一种重要的算法设计思想。它常常借助深度优先遍历(DFS)来实现,另外一类常借助DFS来实现的算法是动态规划,因此,二者的编码往往会使用到递归。在Leecode上有很多会用到回溯法来解决的编程问题。本文将从Leetcode题目求解的角度出发,通过实践来探讨一下回溯法编程的基本套路import copyclass Solution:...原创 2021-03-01 03:56:41 · 363 阅读 · 0 评论 -
深入理解回溯法:从Leetcode实践出发【2】(题号77、39、40、216、698、93)
回溯法(Backtracking)是一种重要的算法设计思想。它常常借助深度优先遍历(DFS)来实现,另外一类常借助DFS来实现的算法是动态规划,因此,二者的编码往往会使用到递归。在Leecode上有很多会用到回溯法来解决的编程问题。本文将从Leetcode题目求解的角度出发,通过实践来探讨一下回溯法编程的基本套路原创 2021-02-02 06:33:20 · 628 阅读 · 5 评论 -
深入理解回溯法:从Leetcode实践出发【3】(题号22、79、131、254、526、1079)
回溯法(Backtracking)是一种重要的算法设计思想。它常常借助深度优先遍历(DFS)来实现,另外一类常借助DFS来实现的算法是动态规划,因此,二者的编码往往会使用到递归。在Leecode上有很多会用到回溯法来解决的编程问题。本文将从Leetcode题目求解的角度出发,通过实践来探讨一下回溯法编程的基本套路原创 2021-03-05 08:12:17 · 344 阅读 · 0 评论 -
深入理解回溯法:从Leetcode实践出发【4】(题号51、52、37)
回溯法(Backtracking)是一种重要的算法设计思想。它常常借助深度优先遍历(DFS)来实现,另外一类常借助DFS来实现的算法是动态规划,因此,二者的编码往往会使用到递归。在Leecode上有很多会用到回溯法来解决的编程问题。本文是回溯法系列文章的最后一弹,其中选取的Leetcode题目难度级别为Hard,而且是非常经典的算法问题原创 2021-03-17 06:24:36 · 383 阅读 · 0 评论 -
深入理解动态规划:从Leetcode实践出发【1】(题号70、139、140)
动态规划是一种非常重要的算法设计思想。历史上有很多著名的算法都是基于这种思想设计而来的,例如:Needleman–Wunsch算法、CYK算法、FFT算法、维特比算法等等。动态规划的核心思想有两个:首先是将一个大问题拆解为若干子问题;其次是将曾经计算过的结果储存起来以备多次使用。实践中,动态规划方面的编程题目,变化多端,难度较大。本系列教程,博主希望可以帮助读者做到从入门到精通,循序渐进地深入理解并掌握相关题目的求解技巧原创 2021-02-21 08:30:03 · 428 阅读 · 0 评论 -
深入理解动态规划:从Leetcode实践出发【2】(题号96、91、338、343)
动态规划是一种非常重要的算法设计思想。历史上有很多著名的算法都是基于这种思想设计而来的,例如:Needleman–Wunsch算法、CYK算法、FFT算法、维特比算法等等。动态规划的核心思想有两个:首先是将一个大问题拆解为若干子问题;其次是将曾经计算过的结果储存起来以备多次使用。实践中,动态规划方面的编程题目,变化多端,难度较大。本系列教程,博主希望可以帮助读者做到从入门到精通,循序渐进地深入理解并掌握相关题目的求解技巧原创 2021-02-21 09:57:10 · 287 阅读 · 0 评论 -
深入理解动态规划:从Leetcode实践出发【3】(题号1143、718)
动态规划是一种非常重要的算法设计思想。历史上有很多著名的算法都是基于这种思想设计而来的,例如:Needleman–Wunsch算法、CYK算法、FFT算法、维特比算法等等。动态规划的核心思想有两个:首先是将一个大问题拆解为若干子问题;其次是将曾经计算过的结果储存起来以备多次使用。实践中,动态规划方面的编程题目,变化多端,难度较大。本系列教程,博主希望可以帮助读者做到从入门到精通,循序渐进地深入理解并掌握相关题目的求解技巧原创 2021-02-23 13:38:36 · 369 阅读 · 0 评论 -
深入理解动态规划:从Leetcode实践出发【4】(题号121、300、516、416、730)
动态规划是一种非常重要的算法设计思想。历史上有很多著名的算法都是基于这种思想设计而来的,例如:Needleman–Wunsch算法、CYK算法、FFT算法、维特比算法等等。动态规划的核心思想有两个:首先是将一个大问题拆解为若干子问题;其次是将曾经计算过的结果储存起来以备多次使用。实践中,动态规划方面的编程题目,变化多端,难度较大。本系列教程,博主希望可以帮助读者做到从入门到精通,循序渐进地深入理解并掌握相关题目的求解技巧原创 2021-02-23 17:17:17 · 378 阅读 · 0 评论 -
深入理解动态规划:从Leetcode实践出发【5】(题号198、213、983、416、322)
动态规划是一种非常重要的算法设计思想。历史上有很多著名的算法都是基于这种思想设计而来的,例如:Needleman–Wunsch算法、CYK算法、FFT算法、维特比算法等等。动态规划的核心思想有两个:首先是将一个大问题拆解为若干子问题;其次是将曾经计算过的结果储存起来以备多次使用。实践中,动态规划方面的编程题目,变化多端,难度较大。本系列教程,博主希望可以帮助读者做到从入门到精通,循序渐进地深入理解并掌握相关题目的求解技巧原创 2021-02-25 09:31:31 · 1169 阅读 · 0 评论 -
深入理解动态规划:从Leetcode实践出发【6】(题号62、63、64)
动态规划是一种非常重要的算法设计思想。历史上有很多著名的算法都是基于这种思想设计而来的,例如:Needleman–Wunsch算法、CYK算法、FFT算法、维特比算法等等。动态规划的核心思想有两个:首先是将一个大问题拆解为若干子问题;其次是将曾经计算过的结果储存起来以备多次使用原创 2017-12-28 13:43:40 · 4443 阅读 · 2 评论 -
深入理解动态规划:从Leetcode实践出发【7】(题号53)(最大连续子序列和问题)
最大连续子序列和问题是一道很有意思也很经典的算法题。它的直观上的求解显而易见、非常容易,但是它的优化求解直到上世纪80年代才被发现,这便是基于动态规划设计的Kadane算法原创 2017-10-15 07:01:53 · 7143 阅读 · 0 评论 -
深入理解动态规划:从Leetcode实践出发【8】(题号718、72)
动态规划是一种非常重要的算法设计思想。历史上有很多著名的算法都是基于这种思想设计而来的,例如:Needleman–Wunsch算法、CYK算法、FFT算法、维特比算法等等。动态规划的核心思想有两个:首先是将一个大问题拆解为若干子问题;其次是将曾经计算过的结果储存起来以备多次使用原创 2017-12-29 16:49:31 · 2776 阅读 · 4 评论