自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(39)
  • 收藏
  • 关注

原创 算法通关村 —— 滑动窗口与堆结合

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。因此,当我们后续继续向右移动窗口时,这个值就永远不可能出现在滑动窗口中了,我们可以将其。中,在这种情况下,这个值在数组 nums 中的位置出现在。中,此时堆顶的元素就是堆中所有元素的最大值。,表示元素 num 在数组中的下标为 index。可以帮助我们实时维护一系列元素中的最大值。此时,堆顶元素就是滑动窗口中的最大值。本题初始时,我们将数组 nums 的。是首先应该考虑的思路。

2023-11-01 20:55:46 214

原创 算法通关村 —— 滑动窗口经典问题

numsl,numsl + 1,..., numsr - 1,numsr] ,并返回其长度。如果两个字符串仅仅是字幕出现位置不一样,则称两者相互为对方的一个排列,或异位词。判断两个字符串是否为排列,也是字符串的一个基本算法。给定一个字符串s, 找出至多包含两个不同字符串的最长子串t, 并返回该子串的长度。找到字符串中所有字母异位词,给定两个字符串 s 和 p,找到s 中所有 p 的 异位词 的子串,前面我们已经了解了滑动窗口的基本思想,今天让我们一起来完成有关滑动窗口的经典算法题。不考虑答案输出的顺序。

2023-11-01 20:35:00 217

原创 算法通关村 —— 原来滑动窗口如此简单

滑动窗口是双指针的一种类型,主要关注两个指针之间元素的情况,因此范围更小一些,而双指针的应用范围更大,花样也更多。为了方便演示,我们将示例序列再增加几个元素{1,3,5,4,7,8,9,2},则图示如下,题目要求找到最长的连续递增子序列。当变量移动的时,其中间的元素必然会发生变化,因此就有了这种不断滑动的效果。尽管[1,3,5,7] 也是升序的子序列,但它不是连续的,因为 5 和 7 在原数组里被4隔开。滑动窗口的思想非常简单,如下图所示,假如窗口的大小是3,当不断有新数据来时,我们会。

2023-10-26 20:52:21 104 1

原创 算法通关村 —— 继续研究超大规模数据问题

目录算法通关村 —— 继续研究超大规模数据问题1. 对20GB文件进行排序2.超大文本中搜索两个单词的最短距离3.从10亿数字中寻找最小的100万个数字在接触学习了前面关于海量数据算法的知识和题目后,让我们详细来看几道典型的海量数据场景下的查找问题。题目要求: 假设你有一个20GB的文件,每行一个字符串,请说明如何对这个文件进行排序?分析: 这里给出大小是20GB,其实面试官就在暗示你不要将所有的文件都装入到内存里,因此我们只能将文件划分成一些块,每块大小是xMB,x就是可用内存的大小,例如1GB一 块,那

2023-10-25 21:13:46 75

原创 算法通关村 —— 海量数据的热门算法题

1) 根据 10MB 的内存限制,确定统计区间的大小,就是第二次遍历时的 bitArr 大。2) 利用区间计数的方式,找到那个计数不足的区间,这个区间上肯定有没出现的数。3) 对这个区间上的数做 bit map 映射,再遍历bit map,找到一个没出现的数即可。

2023-10-25 20:31:55 29

原创 算法通关村 —— 位运算在查找重复元素中的秒用

在大部分算法中,默认给定的数据量都很小的,例如只有几个或者十几个元素,但是如果将数据量提高到百万甚至十几亿,那处理逻辑就会发生很大差异,这也是算法考查中,经常出现的类问题。问题的热身题,如果去掉“只有4KB”的要求,我们可以先创建一个大小为N的数组,然后将这些数据放进来,但是整数最大为32000。如果发现数组元素是v,那么就将位置为V的设置为1,碰到重复元素,就输出一下。的整数数组,如果用整数存储需要16GB左右的空间,而如果使用位存储,就可以用。,无法在内存中放下,则需要考虑。,且N的取值不定,若只有。

2023-10-25 09:33:25 55

原创 算法通关村 —— 堆能高效解决的经典问题

排序工作就完成了。看一个例子,我们对上面第一章的序列 [12 23 54 2 65 45 92 47 204 311进行排序,首先构建一个大顶堆,然后每次我们都让根元素出堆,剩下的继续调整为大顶堆!出堆的序列刚好是: 204、92、65、54、47、45......。也就是刚好是。

2023-10-24 23:01:10 26

原创 算法通关村 —— 原来这就是堆

堆的价值就在于大顶堆的根节点是整个树最大的那个增加时会根据根的大小来决定要不要加,而删除操作只删除根元素。这个特征可以在很多场景下有奇妙的应用,后面的算法题全都基于这一点。这里可能有些人还有疑问,感觉不管插入还是删除,堆的操作都不简单,那为什么还说堆的效率比较高呢?这是因为堆元素的数量是有限制的,一般不用将所有的元素都放到堆里。后面题目中可以看到在序列中找K大,则堆的大小就是K。如果K个链表合并,那么堆就是K。原理后面详细展开。说了这么多堆的性质,我们来看一下堆到底怎么解决问题的。

2023-10-24 09:50:41 40

原创 算法通关村 —— 数组实现加法专题

这里关键点在于,什么时候会出现这种情况,只有一种情况,就是一定要有9, 99,999,9999……到这里就很简单了,我们只需要申请一个空间比A大一个长度的数组B,然后把B[0] 设置为1即可,其他位置就默认为0了,这样代码就非常的简洁,具体实现如下:。也就是用字符串来表示数字,然后计算它们的和。例如digits = [9,9,9,9], 从后向前加时,到A[0] 的位置计算为0,需要再次进位但是数组长度是确定的,不能保存了,那怎么办呢。再比如,给定两个数,一个用数组存储,一个是普通的正数,又该如何处理呢?

2023-10-18 19:47:34 51

原创 算法通关村 —— 反转字符串里的单词问题解析

对于字符串可变的语言,就不需要额外开辟空间了,直接在字符串上原地实现。在这种情况下,反转字符和去除空格就可以放在一起完成了。但是这种方式毕竟用了语言特性,而没有考察到算法,所以面试时一般不会用,对于上面提到的功能,我们还是自己编写函数来实现吧!单词是由非空格字符串组成的字符串,s中至少使用一个空格将字符串中的 单词 分隔开。问题难度不是很大,和反转字符串其实差不多,下面我们从两个角度来解决该问题。给定一个字符串s,逐个反转字符串中的所有。反转后的字符串不应包含额外的空格。并用单个空格相连的字符串。

2023-10-15 22:11:34 49

原创 算法通关春 —— 字符串转换问题

字符串里存放的可以是字母,可以是数字,也可以是特殊字符,字母可以为大写也可以为小写,所以就使得字符串有一类很常见的转换题目,这些题目转换类型变了,但本质不变,都是想办法遍历到字符串中每个字符,然后判断当前元素需不需要转。⚪ 第四步:通过与ASCII码进行比较判断当前字符是否为数字,若是则转换为整数,最前面的0需要将其去掉,这里我们只需将该转换后的数字加到res中,则前面的0就不影响结果了。⚪ 第二步:判断第一个字符为 + 或 - 的情况,因此可以设置一个变量sign,1为+,-1为-

2023-10-15 20:20:14 47

原创 算法通关村 —— 进制专题学习

在算法中,数字与数学基础问题是非常基础、非常重要且面试经常出现的题目,今天让我们一起来学习有关进制的算法专题!

2023-10-12 19:24:01 48

原创 算法通关村 —— 位运算实现加减乘除

在计算机中,位运算的效率比单纯加减乘除的效率更高,因此在高性能软件的源码中大量应用。而且计算机里各种运算本质上都是位运算,所以也是高频考题,让我们一起学习下面几个问题。

2023-10-09 21:34:12 80

原创 算法通关村 —— 移位运算解析

对于0和整数,可以说将一个数算术右移k位和将这个数除以2^k等价,因为整数除法是向0取整,右移运算是向下取整,也是向0取整。3)-50的二进制表示为10110010,补码为11001110,-50算术右移两位后二进制表示为 11110011,对应的二进制原码为10001101,即为-13;2)50的二进制表示为00110010,50右移2位后二进制表示位00001100,结果为12,由于正数或0的第一位都位0,所以对于0和正数,无论是算术右移还是逻辑右移,其高位都是补0,所以两者右移的结果是相同的。

2023-10-08 11:02:18 69

原创 归并排序原理解析及实现

将两两已经有序的子序列合并成一个有序序列,最终得到有序的大序列。就是图中下侧的满二叉树。用到的算法都是合并两个有序数组。归并排序(MERGE-SORT)原理其实很简单,就是将大的无序序列分为若干个小的数组,然后利用。将序列通过递归拆分成子序列, 递归深度为logn。就是图中上侧的满二叉树。从图上看可以看到这种结构很像上下两棵满二叉树套在一起。的思想来实现的排序方法,其实就是经典的。将大的序列不断分成小的序列进行排序求解。将分后所得的各个答案“合”在一起。

2023-10-03 23:42:43 81

原创 快速排序算法原理解析(基于 Java 实现)

通过上面非常非常详细的解析,是不是已经掌握了呢,下面让我们再来学习另外一种实现方式,这里采用的就是一个对撞的双指针操作,思路其实差不多,也同样是选出一个pivot元素,然后将比它小的移到其左边,比他大的移到其右边。⚪ 折中的情况是每次选择的都是中间结点,此时两侧序列每次都是长度相等的序列,类似于折半,则此时的时间复杂度为O(nlogn))⚪ 最坏的情况就是如果每次选择的恰好都是low结点作为pivot,而元素恰好都是逆序的,此时时间复杂度为O(n^2)原理不是很简单,接下来就让我们一起通过代码来解析吧!

2023-09-26 22:01:20 58

原创 算法通关村 —— 透彻理解二叉树中序遍历的应用

根据中位数的定义我们可知,当m+n为奇数,中位数是有序数组的第(m+n)/2个元素,为偶数,中位数是第(m+n)/2个元素和第(m+n)/2 + 1个元素的平均值。只有nums1的前k/2 - 1个数和nums2的前k/2 - 1个,因此比其小的数最多只有k-2个,因此nums1[k/2 - 1]不可能是第k个数,那么便可以排除掉nums1[0]到nums[k/2 - 1]的数,也就是一次砍掉一半。⚪ 如果nums1[k/2-1] < nums2[k/2-1],则比nums1[k/2-1]小的数。

2023-09-23 19:40:54 111

原创 算法通关村 —— 轻松解决搜索树难题

可能看起来顿时感到害怕,毕竟碰到任意就头大,但先别慌,我说了,要充分利用二叉搜索树的特征,就是他是有序的,所以一个结点和其他结点值的绝对差最小时,该结点只能为其左或右的相邻节点,所以不还是很前面的题一样嘛。作为基础,这道题的思路自然不会很复杂,只需通过递归的方式,在中序遍历的时候实时检查当前节点是否大于前一个节点的值即可,记住一定要实时更新前一个结点的值!⚪ 如果搜索值大于根节点的值,说明搜索值在根节点的右子树,这时候只需递归查找该根节点的右子树。⚪ 若右子树不空,则右子树上所有节点值均大于它的根节点;

2023-09-22 22:07:18 62

原创 算法通关村 —— 透彻理解二分查找

二分查找其实用了分治的思想,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题直到最后子问题可以简单地直接求解。我们可以使用循环来让区间中间值与目标值进行比较,若区间中间值大于目标值,则接下去查找该区间的左半部分,否则则查找右半部分,不断切分下去,直到区间中间值等于目标值,则找到目标值索引。1)若当前查找索引的值等于目标值且不为最左端,则往左移直到值不为目标值,则最后该索引+1则为目标值的最左一个。2)若当前查找索引已在最左端,且等于目标值,则该索引即为寻找的目标值位置。

2023-09-22 12:55:14 78

原创 算法通关村 —— 轻松搞定树的深度问题

前面我们研究的都是二叉树,那要是换成N叉树呢,其实也是大差不差的,只不过树结构改变了而已,原来是遍历左右孩子,现在需要遍历节点的所有子节点,也就是遍历该节点所有子节点的列表而已,遍历时多加了个List的for循环。在此之前,我们已经学习了很多树的基础知识和经典算法,今天让我们一起来学习几道比较有难度的题目——有关树的深度和高度问题,这几道对递归的要求高一些,一起来看看吧!既然树有最大深度,那就会有最小深度。最小深度的一层必须要有节点,最小深度指的是从根节点到最近叶子节点的最短路径上的节点数量!

2023-09-21 18:51:32 99

原创 算法通关村 —— 轻松搞定二叉树里的双指针难题

其实就是同时对两个二叉树进行前序遍历,先判断两棵树的根节点是否相同,如果相同再分别判断左右子节点是否相同,判断过程中只要有一个不相同就要返回false,说明两棵树不相同,只有全部相同最后才会返回true,两棵树才相同。判断两树是否相同是判断相同位置的节点是否相同,所以若要判断两树是否对称,只需判断左树的外侧节点和右树的外侧节点是否相同,以及左树的内侧节点和右树的外侧节点是否相同。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

2023-09-19 21:40:26 88

原创 算法通关村 —— 迭代实现二叉树的前中后序遍历

再来看中序遍历,中序遍历顺序为左中右,先访问二叉树左子树的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是把节点值存进res列表)。然后处理其父节点,再处理其父节点的右节点。在使用迭代法写中序遍历时,就需要借用指针的遍历来帮助访问接待你,栈则用来处理节点上的元素。这里介绍的是反转法来迭代实现后序遍历,我们知道后序遍历顺序为左右中,所以我们如果得到了中左右的遍历顺序结果,通过反转的方法便可得到后序遍历结果。所以方法很简单,只需改造以下前序遍历,让他先访问右节点便好。

2023-09-18 19:35:09 88

原创 算法通关村 —— 树的层次遍历问题

目录树的层次遍历问题1 层次遍历简介2 树的层次遍历2.1 二叉树普通遍历2.2 二叉树自底向上遍历2.3 二叉树锯齿形遍历2.4 N叉树的层次遍历3 处理每层元素的题目3.1 在每个树行中找最大值二叉树的层次遍历是一个比较简单的问题,层次遍历又叫广度优先,从根节点开始,先访问根节点下面一层全部元素,再访问之后的层次,类似金字塔一层层访问,基本过程如下:给定一个二叉树,将其按层遍历得到节点值。(逐层地,从左到右访问所有节点)例如给定的二叉树为:做法比较容易,先将根节点放到队列中,访问完当前节点后就将其

2023-09-18 17:20:53 304

原创 算法通关村 —— 如何使用中序和后序来恢复一棵二叉树

中左右。

2023-09-16 18:41:35 311 1

原创 算法通关村 —— LRU的设计与实现

使用key-value创建新结点,在双向链表头部添加该节点,并将key和该节点添加进哈希表中。在双向链表的实现中,使用伪头部节点(dummy head)和伪尾部(dummy tail)标记界限,这样在添加和删除节点就不需要检查相邻节点是否存在。故我们要确认元素位置只需访问哈希表,找出缓存项在双向链表中的位置,随后将其移动到双向链表头部,即可在O(1)时间内完成get或者put操作。,通过哈希表定位到该节点在双向链表中的位置,将对应节点值更新为value,将该节点移到双向链表头部。:先判断key是否存在。

2023-09-14 16:39:52 125 1

原创 算法通关村 —— 队栈实现问题解析

将一个栈作为输入栈,用于压入push传入的数据;每次pop或peek时,若输出栈为空则将输入栈的全部数据依次弹出并压入输出栈,这样输出栈从栈顶往栈底的顺序就是队列从队首往队尾的顺序。时,先将元素入队queue2,此时queue2的前端元素为新入栈的元素,再将queue1和queue2互换,则queue1的元素即为栈内的元素,queue1的前端和后端分别对应栈顶和栈底。:在使用队列实现栈时,满足队列前端的元素是最后入栈的元素。:使用两个队列实现,满足栈的特性,即最后入栈的元素最先出栈,

2023-09-12 18:36:02 58

原创 算法通关村 —— 队列的实现

对于基于链表,由于链表长度随时可变,实现较为简单。而对于基于数组,会比较麻烦,后面再做学习。基于链表实现队列的方式比较简单,队列的实现方式有两种形式:基于。先入队先出队,后入队后出队。2 队列的实现(基于链表)

2023-09-11 20:58:27 64

原创 算法通关村 —— 计算器问题解析

若读到一个运算符,或者遍历到字符串末尾,即认为是遍历到数字末尾,因为我们先计算了乘除,再压加减号的数字入栈,所以后面若遍历到符号则证明已经遍历完。总的来说便是去遍历指定的字符串s,并用变量preSign来记录每个数字前的运算符,第一个数字之前的运算符视为加号。最后,对乘除号后的数字,可以直接与栈顶元素计算,并替换栈顶元素为计算后的结果。栈有很多经典的问题,前面我们已经学习了像括号匹配这样经典的问题,除此之外,表达式计算和计算器问题天然的适合使用栈来解决,不过,解决起来可能略复杂一些。将数字的相反数入栈;

2023-09-06 22:32:06 70 1

原创 算法通关村 —— 括号匹配问题解析

本题难度其实不大,主要解决的是判断两个符号是不是同一组括号,所以我们就要让同一组括号联系起来。所以我们可以用哈希表先将所有符号先存储,左半括号做key,右半括号做value。遍历字符串时,遇到左半边括号就入栈,遇到右半边括号就与栈顶符号比较,如果匹配就把栈顶的左半边括号出栈,然后继续执行判断,如果不匹配就返回false,最后如果栈为空,说明所有括号匹配成功,那么就返回true。首先看题目要求,给定一个只包括'(', ')', '{', '}', '[', ']' 的字符串s,判断字符串是否有效。

2023-09-06 21:39:37 194 1

原创 算法通关村 —— 如何基于数组链表实现栈

栈和队列是比较特殊的线性表,又称为访问受限的线性表。栈是很多表达式、符号等运算的基础,也是递归的底层实现。栈底层实现任然是链表或者顺序表,栈与线性表最大区别是数据的存取被限制了,其插入和删除只允许在线性表的一段进行。一般而言,允许操作的一段称为栈顶,不可操作的一端称为栈底,插入元素的操作称为入栈,删除元素的操作称为出栈。在此之前我们已经学习过没有虚拟节点时对链表头元素进行插入和删除了,而这里基于链表实现栈是一模一样的。采用顺序表实现的栈,内部以数组为基础,实现对元素的存取操作。2)pop():弹出元素E。

2023-09-06 20:08:20 97 1

原创 算法通关村 —— 颜色分类问题(黄金挑战)

给定一个包含红色、白色和蓝色、共n个元素的数组nums,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。如果是0,我们放到左边,如果是2,放到右边。在这一题,我们可以对数组进行两次遍历,第一次,我们将数组所有的0交换到数组头部,这样第二次只需处理1和2的问题就行了。上面的方法效率还不错,但我们能否一次遍历就解决呢,当然也是可以的。我们可以将其量化,使用正数0、1、2分别表示红色、白色和蓝色。要求不适用库的sort函数。这个题是非常经典的双指针问题,而且可以使用多种方式的双指针。

2023-09-05 16:52:36 144

原创 算法通关村 —— 双指针的妙用(删除数组元素专题)

而很多算法题都需要多轮、大量移动元素,这就导致执行效率地下,解决该问题是数组算法的一个重要问题,其中一种非常好用的方式就是双指针思想。在数组中其最基本的题便为,给定一个有序数组nums,让你原地删除重复出现的元素,使每个元素只出现一次,返回删除数组后数组的新长度。本题使用双指针最方便,思想其实都是一样的,一个指针负责数组遍历,一个指向有效数组的最后一个位置。甚至一个都不要呢,其实也是可以的。由于删除的时候,从删除位置开始的元素都要向前移动,所以如果有多值为val,则会导致反复移动,效率低下。

2023-09-05 01:39:54 79

原创 算法通关村 —— 不简单的数组增删改查

在面试中,数组大部分情况下都是int类型的,接下来我们就用int类型来实现数组增删改查的基本功能,接下来就让我们自己动手来实现吧。

2023-09-04 18:20:08 134 1

原创 算法通关村第二关 —— k个一组反转(黄金挑战)

这可以说是链表中最难的一个问题了,搞清楚了证明我们的链表即将大成。这个题目是这样的,给你一个链表,每个结点一组进行翻转,请你返回翻转后的链表。k是一个正整数,它的值小于或等于链表长度。如果节点总数不是k的整数倍,那么将最后剩余的结点保持原有顺序。其实就是将链表分组,然后再分别进行翻转,思路不困难,难在具体的实现,下面我们学习两种方法。

2023-09-01 21:05:39 110 1

原创 算法通关村第一关 —— 链表中环的问题(黄金挑战)

第一种题型我们已经学会判断是否有环了,那当环存在时,就一定会有入口,那么如何确定入口的位置呢,我们用图的方法来理解比较好。则 a = c + (n-1)LEN,说明在第二次相遇的时候,快指针从Z出发已经转了(n-1)圈回到Z,然后两指针再一起向前走c步,此时一起到达Y,则又相遇了,所以也是一样的道理,代码并不会改变,所以第二次相遇的位置就是环的入口。确定是否有环,最有效的方法其实是双指针。快指针一次走两步,慢指针一次走一步,如果快的能到达表尾就不会有环,如果存在环,那两指针必定会在某个位置相遇。

2023-09-01 19:19:51 121 1

原创 算法通关村第二关 —— 指定区间反转问题解析

指定区间链表的反转本质上和链表反转没有什么区别,只不过让我们学会更加灵活地去操作使用链表,通过这个题型的学习也提升了我们以后应对不同情况处理链表的能力,本质上就是增删改查的基础,所以一定要脚踏实地,夯实基础。

2023-09-01 13:42:30 148 1

原创 算法通关村第二关 —— 终于学会链表反转

链表反转真的非常重要,因为他考察了我们对链表结构的了解程度,以及对链表操作方法的熟练程度,所以是我们一定要学会的题型之一,相信通过我这篇文章,大家都可以很清晰地学会链表反转了。

2023-08-31 22:47:47 211

原创 算法通关村第一关 —— 链表经典问题之公共子结点笔记

我们知道两个链表长度不一定相等,但是在第一个公共子结点之后的长度是相等的,那么我们可不可以让两个链表长度相等呢,因为长度相等后,我们就可以将两者的结点对应上了,共同遍历知道找到第一个公共子节点,这便是这个方法的思路。而且,两个拼接后的链表的尾部恰好就是两原链表的尾部,那这不和我们前面说的方法对应上了吗,因为在第一个公共结点之后的结点都是相同的,所以尾部的结点都是相同的,离尾部最远一组相同的结点或者说是我们从头遍历最早得到的一组相同结点,即为我们所找的第一个公共结点。那么4就是我们所找的第一个公共子结点。

2023-08-29 21:30:03 308

原创 算法通关村第一关 —— 链表青铜挑战笔记

在该种情况我们可以排除链表为空的情况了,所以接下来只需找到插入位置的前一个结点cur,令新结点的next指向cur的后继,再令其后继的pre指针指向新结点。然后再令cur的next指针指向新结点,令新结点的pre指针指向前驱。删除中间结点,可以从头结点开始,按顺序遍历到删除结点的前一个结点,令该结点的后继指向删除结点的后继,令删除结点的后继的pre指针指向前一个结点,并返回所删除的结点的数值。删除尾结点只需将尾结点的前一个结点的pre指针指向null,再令其前一个结点为新的尾结点,最终返回原尾结点的数值。

2023-08-27 21:17:27 505

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除