数据结构和算法
文章平均质量分 92
数据结构和算法专栏旨在帮助读者深入理解和应用数据结构与算法的核心概念。通过清晰的讲解和实用的示例,专栏将介绍各种常见的数据结构(如数组、链表、栈、队列、树等)和经典的算法(如排序、查找、图算法等)。
我乐了.
这个作者很懒,什么都没留下…
展开
-
定位问题才能更好地解决问题:开发前的复杂度分析与技术选型
在开发前,一定要对问题的复杂度进行分析,做好技术选型。这就是定位问题的过程。只有把这个过程做好,才能更好地解决问题。常用的分析问题的方法有以下 4 种复杂度分析。估算问题中复杂度的上限和下限。定位问题。根据问题类型,确定采用何种算法思维。数据操作分析。根据增、删、查和数据顺序关系去选择合适的数据结构,利用空间换取时间。编码实现。原创 2024-01-19 10:07:01 · 366 阅读 · 0 评论 -
动态规划:如何通过最优子结构,完成复杂问题求解?
动态规划领域有很多经典问题,我们讲述了最短路径的问题。需要明确的是,动态规划并不简单,动态规划的适用范围也没有那么广。如果你不是专门从事运筹优化领域的工作,对它不了解也很正常。如果在求职过程中,你求职的岗位与运筹优化关系不大,一般而言被考察到动态规划的可能性也是极低的。原创 2024-01-19 10:05:38 · 345 阅读 · 0 评论 -
排序:经典排序算法原理解析与优劣对比
如果对数据规模比较小的数据进行排序,可以选择时间复杂度为 O(n*n) 的排序算法。因为当数据规模小的时候,时间复杂度 O(nlogn) 和 O(n*n) 的区别很小,它们之间仅仅相差几十毫秒,因此对实际的性能影响并不大。但对数据规模比较大的数据进行排序,就需要选择时间复杂度为 O(nlogn) 的排序算法了。归并排序的空间复杂度为 O(n),也就意味着当排序 100M 的数据,就需要 200M 的空间,所以对空间资源消耗会很多。原创 2024-01-19 10:04:06 · 400 阅读 · 0 评论 -
分治:如何利用分治法完成数据查找?
分治法经常会用在海量数据处理中。这也是它显著区别于遍历查找方法的优势。在面对陌生问题时,需要注意原问题的数据是否有序,预期的时间复杂度是否带有 logn 项,是否可以通过小问题的答案合并出原问题的答案。如果这些先决条件都满足,你就应该第一时间想到分治法。原创 2024-01-19 10:02:43 · 292 阅读 · 0 评论 -
递归:如何利用递归求解汉诺塔问题?
递归的核心思想是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况。另外这个解决问题的函数必须有明显的结束条件,这样就不会产生无限递归的情况了。递归的应用非常广泛,之后我们要讲的很多数据结构和算法的编码实现都要用到递归,例如分治策略、快速排序等等。原创 2024-01-19 10:01:35 · 324 阅读 · 0 评论 -
哈希表:如何利用好高效率查找的“利器”?
哈希表在我们平时的数据处理操作中有着很多独特的优点,不论哈希表中有多少数据,查找、插入、删除只需要接近常量的时间,即 O(1)的时间级。实际上,这只需要几条机器指令。哈希表运算得非常快,在计算机程序中,如果需要在一秒钟内查找上千条记录通常使用哈希表(例如拼写检查器),哈希表的速度明显比树快,树的操作通常需要 O(n) 的时间级。哈希表不仅速度快,编程实现也相对容易。如果不需要有序遍历数据,并且可以提前预测数据量的大小。那么哈希表在速度和易用性方面是无与伦比的。原创 2024-01-19 10:00:31 · 304 阅读 · 0 评论 -
树和二叉树:分支关系与层次结构下,如何有效实现增删查?
对于查找操作,如果是普通二叉树,则查找的时间复杂度和遍历一样,都是 O(n)。如果是二叉查找树,则可以在 O(logn) 的时间复杂度内完成查找动作。树结构在存在“一对多”的数据关系中,可被高频使用,这也是它区别于链表系列数据结构的关键点。原创 2024-01-19 09:59:06 · 823 阅读 · 0 评论 -
字符串:如何正确回答面试中高频考察的字符串匹配算法?
这节课我们介绍了字符串匹配算法,它在平时代码编写中都比较常用。字符串的逻辑结构和线性表极为相似,区别仅在于串的数据对象约束为字符集。但是,字符串的基本操作和线性表有很大差别:在线性表的基本操作中,大多以“单个元素”作为操作对象;在字符串的基本操作中,通常以“串的整体”作为操作对象;字符串的增删操作和数组很像,复杂度也与之一样。但字符串的查找操作就复杂多了,它是参加面试、笔试常常被考察的内容。原创 2024-01-19 09:57:17 · 367 阅读 · 0 评论 -
数组:如何实现基于索引的查找?
在实际操作中,我们还要注意根据数组的优缺点合理区分数组和链表的使用。数组定义简单,访问方便,但在数组中所有元素类型必须相同,数组的最大长度必须在定义时给出,数组使用的内存空间必须连续等。相对而言,数组更适合在数据数量确定,即较少甚至不需要使用新增数据、删除数据操作的场景下使用,这样就有效地规避了数组天然的劣势。在数据对位置敏感的场景下,比如需要高频根据索引位置查找数据时,数组就是个很好的选择了。原创 2024-01-19 09:54:20 · 340 阅读 · 0 评论 -
队列:先进先出的线性表,如何实现增删查?
在时间复杂度上,循环队列和链式队列的新增、删除操作都为 O(1)。而在查找操作中,队列和线性表一样只能通过全局遍历的方式进行,也就是需要 O(n) 的时间复杂度。在空间性能方面,循环队列必须有一个固定的长度,因此存在存储元素数量和空间的浪费问题,而链式队列不存在这种问题,所以在空间上,链式队列更为灵活一些。通常情况下,在可以确定队列长度最大值时,建议使用循环队列。无法确定队列长度时,应考虑使用链式队列。队列具有先进先出的特点,很像现实中人们排队买票的场景。原创 2024-01-19 09:52:58 · 361 阅读 · 0 评论 -
栈:后进先出的线性表,如何实现增删查?
栈继承了线性表的优点与不足,是个限制版的线性表。限制的功能是,只允许数据从栈顶进出,这也就是栈后进先出的性质。不管是顺序栈还是链式栈,它们对于数据的新增操作和删除操作的时间复杂度都是 O(1)。而在查找操作中,栈和线性表一样只能通过全局遍历的方式进行,也就是需要 O(n) 的时间复杂度。栈具有后进先出的特性,当你面对的问题需要高频使用新增、删除操作,且新增和删除操作的数据执行顺序具备后来居上的相反关系时,栈就是个不错的选择。例如,浏览器的前进和后退,括号匹配等问题。原创 2024-01-19 09:51:35 · 331 阅读 · 0 评论 -
如何完成线性表结构下的增删查?
好了,铺垫完数据结构的基本概念后,我们就正式进入到这个课程中的第一个数据结构的学习,线性表。线性表是 n 个数据元素的有限序列,最常用的是链式表达,通常也叫作线性链表或者链表。在链表中存储的数据元素也叫作结点,一个结点存储的就是一条数据记录。每个结点的结构包括两个部分:第一是具体的数据值;第二是指向下一个结点的指针。在链表的最前面,通常会有个头指针用来指向第一个结点。对于链表的最后一个结点,由于在它之后没有下一个结点,因此它的指针是个空指针。链表结构,和小朋友手拉手站成一排的场景是非常相似的。原创 2024-01-19 09:50:18 · 802 阅读 · 0 评论 -
增删查:掌握数据处理的基本操作,以不变应万变
例如,输入数组 a = [1,2,3,4,5,5,6] 中,只有 5 出现了两次,其余都是 1 次。显然 5 出现的次数最多,则输出 5。为了降低时间复杂度,我们引入了 k-v 的字典的数据结构。那么问题来了,究竟是什么原因,促使我们想到了使用字典的数据结构呢?如果不使用字典,改为使用数组行不行呢?为了回答这些问题,我们先看一下究竟此处代码需要对数据进行哪些操作。我们提到过,这段代码处理数据的核心思路是:第一步,根据原始数组计算每个元素出现的次数;第二步,根据第一步的结果,找到出现次数最多的元素。原创 2024-01-19 09:48:19 · 771 阅读 · 0 评论 -
数据结构:将“昂贵”的时间复杂度转换成“廉价”的空间复杂度
好的,这一节的内容就到这里了。这一节是这门课程的总纲,我们重点学习了程序开发中复杂度降低的核心方法论。很多初学者在面对程序卡死了、运行很久没有结果这样的问题时,都会显得束手无策。其实,无论什么难题,降低复杂度的方法就是这三个步骤。只要你能深入理解这里的核心思想,就能把问题迎刃而解。第一步,暴力解法。在没有任何时间、空间约束下,完成代码任务的开发。第二步,无效操作处理。将代码中的无效计算、无效存储剔除,降低时间或空间复杂度。第三步,时空转换。设计合理数据结构,完成时间复杂度向空间复杂度的转移。原创 2024-01-19 09:45:50 · 803 阅读 · 0 评论 -
复杂度:如何衡量程序运行的效率?
复杂度通常包括时间复杂度和空间复杂度。在具体计算复杂度时需要注意以下几点。它与具体的常系数无关,O(n) 和 O(2n) 表示的是同样的复杂度。复杂度相加的时候,选择高者作为结果,也就是说 O(n²)+O(n) 和 O(n²) 表示的是同样的复杂度。O(1) 也是表示一个特殊复杂度,即任务与算例个数 n 无关。复杂度细分为时间复杂度和空间复杂度,其中时间复杂度与代码的结构设计高度相关;空间复杂度与代码中数据结构的选择高度相关。会计算一段代码的时间复杂度和空间复杂度,是工程师的基本功。原创 2024-01-19 09:42:17 · 760 阅读 · 0 评论 -
真题案例(四):大厂真题实战演练
在备战大厂面试时,一定要加强问题解决方法论的沉淀。绝大多数一线的互联网公司讲究的是解决问题的规范性,这就决定了其更关注的是问题解决过程的步骤、方法或体系,而不仅仅是解决后的结果。原创 2024-01-18 15:44:59 · 1250 阅读 · 0 评论 -
真题案例(三):力扣真题训练
在看真题前,我们再重复一遍通用的解题方法论,它可以分为以下 4 个步骤:复杂度分析。估算问题中复杂度的上限和下限。定位问题。根据问题类型,确定采用何种算法思维。数据操作分析。根据增、删、查和数据顺序关系去选择合适的数据结构,利用空间换取时间。编码实现。【题目】 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后的数组和新的长度,你不需要考虑数组中超出新长度后面的元素。要求:空间复杂度为 O(1),即不要使用额外的数组空间。例如,给定数组 nums = [1,1,2],函数应原创 2024-01-18 15:43:28 · 1079 阅读 · 0 评论 -
真题案例(二):数据结构训练
解决代码问题的方法可以分为以下 4 个步骤:复杂度分析。估算问题中复杂度的上限和下限。定位问题。根据问题类型,确定采用何种算法思维。数据操作分析。根据增、删、查和数据顺序关系去选择合适的数据结构,利用空间换取时间。编码实现。【题目】 给定一个字符串,逐个翻转字符串中的每个单词。例如,输入:"This is a good example",输出:"example good a is This"。如果有多余的空格需要删除。【解析】 在本课时开头,我们复习了解决代码问题的方法论,下面我们按照解题步骤进行详细分析。原创 2024-01-18 15:31:38 · 719 阅读 · 0 评论 -
真题案例(一):算法思维训练
二分查找包括两部分,其一是二分策略,其二是终止条件。原创 2024-01-18 15:29:15 · 806 阅读 · 0 评论