![](https://img-blog.csdnimg.cn/20201014180756930.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
刷题
文章平均质量分 86
刷题
Joey Liao
这个作者很懒,什么都没留下…
展开
-
算法-二叉堆及优先级队列
首先,二叉堆和二叉树有啥关系呢,为什么人们总是把二叉堆画成一棵二叉树?因为,二叉堆在逻辑上其实是一种特殊的二叉树(完全二叉树),只不过存储在数组里。// 父节点的索引 int parent(int root) {} // 左孩子的索引 int left(int root) {} // 右孩子的索引 int right(int root) {}原创 2022-09-14 19:20:23 · 354 阅读 · 0 评论 -
算法-单调栈和单调队列
栈(stack)是很简单的一种数据结构,先进后出的逻辑顺序,符合某些问题的特点,比如说函数调用栈。单调栈实际上就是栈,只是利用了一些巧妙的逻辑,使得每次新元素入栈后,栈内的元素都保持有序(单调递增或单调递减)。原创 2022-09-13 22:29:10 · 150 阅读 · 0 评论 -
前缀树算法模板
Trie 树又叫字典树、前缀树、单词查找树,是一种二叉树衍生出来的高级数据结构,主要应用场景是处理字符串前缀相关的操作。关于Map和Set,是两个抽象数据结构(接口),Map存储一个键值对集合,其中键不重复,Set存储一个不重复的元素集合。转载 2022-09-06 16:35:45 · 285 阅读 · 0 评论 -
快速排序详解及应用
归并排序算法详解 通过二叉树的视角描述了归并排序的算法原理以及应用,那我就趁热打铁,今天继续用二叉树的视角讲一讲快速排序算法的原理以及运用。代码框架:其实你对比之后可以发现,快速排序就是一个二叉树的前序遍历:另外,前文 归并排序详解 用一句话总结了归并排序:先把左半边数组排好序,再把右半边数组排好序,然后把两半数组合并。同时我提了一个问题,让你一句话总结快速排序,这里说一下我的答案:快速排序是先将一个元素排好序,然后再将剩下的元素排好序。从二叉树的视角,我们可以把子数组 理解成二叉树节点上的值,sro原创 2022-07-08 17:21:03 · 551 阅读 · 0 评论 -
二叉搜索树(构造篇)
二叉搜索树(特性篇)讲了中序遍历对 BST 的重要意义,二叉搜索树(基操篇)写了 BST 的基本操作。本文循序渐进地讲两道题,如何计算所有有效 BST。力扣第 96 题「 不同的二叉搜索树」固定一个根节点后,其形状总数为左子树的组合数和右子树的组合数乘积注意 base case,显然当闭区间肯定是个空区间,也就对应着空节点 null,虽然是空节点,但是也是一种情况,所以要返回 1 而不能返回 0。但是这样会出现很多重叠子问题,这时就需要备忘录来记录已经访问过的组合当然这道题动态规划也可以解决不同的二转载 2022-07-07 21:27:11 · 957 阅读 · 0 评论 -
二叉搜索树(基操篇)
二叉搜索树(特性篇)介绍了 BST 的基本特性,还利用二叉搜索树「中序遍历有序」的特性来解决了几道题目,本文来实现 BST 的基础操作:判断 BST 的合法性、增、删、查。其中「删」和「判断合法性」略微复杂。BST 的基础操作主要依赖「左小右大」的特性,可以在二叉树中做类似二分搜索的操作,寻找一个元素的效率很高。比如下面这就是一棵合法的二叉树:对于 BST 相关的问题,你可能会经常看到类似下面这样的代码逻辑:一、判断 BST 的合法性力扣第 98 题「 验证二叉搜索树」就是让你判断输入的 BST 是转载 2022-07-06 21:47:36 · 273 阅读 · 0 评论 -
二叉搜索树(特性篇)
二叉搜索树并不算复杂,但我觉得它可以算是数据结构领域的半壁江山,直接基于 BST 的数据结构有 AVL 树,红黑树等等,拥有了自平衡性质,可以提供 logN 级别的增删查改效率;还有 B+ 树,线段树等结构都是基于 BST 的思想来设计的。从做算法题的角度来看 BST,除了它的定义,还有一个重要的性质:BST 的中序遍历结果是有序的(升序)。也就是说,如果输入一棵 BST,以下代码可以将 BST 中每个节点的值升序打印出来:寻找第 K 小的元素力扣第 230 题「 二叉搜索树中第 K 小的元素」,一个转载 2022-07-06 20:50:17 · 307 阅读 · 0 评论 -
归并排序详解及应用
就这么说吧,所有递归的算法,你甭管它是干什么的,本质上都是在遍历一棵(递归)树,然后在节点(前中后序位置)上执行代码,你要写递归算法,本质上就是要告诉每个节点需要做什么。你看归并排序的代码框架:看这个框架,也就明白那句经典的总结:归并排序就是先把左半边数组排好序,再把右半边数组排好序,然后把两半数组合并。上述代码和二叉树的后序遍历很像:前文 二叉树(纲领篇) 说二叉树问题可以分为两类思路,一类是遍历一遍二叉树的思路,另一类是分解问题的思路,根据上述类比,显然归并排序利用的是分解问题的思路归并排序的过程可转载 2022-07-01 18:45:36 · 618 阅读 · 0 评论 -
二叉树(序列化篇)
JSON 的运用非常广泛,比如我们经常将变成语言中的结构体序列化成 JSON 字符串,存入缓存或者通过网络发送给远端服务,消费者接受 JSON 字符串然后进行反序列化,就可以得到原始数据了。这就是「序列化」和「反序列化」的目的,以某种固定格式组织字符串,使得数据可以独立于编程语言。本文会用前序、中序、后序遍历的方式来序列化和反序列化二叉树,进一步,还会用迭代式的层级遍历来解决这个问题。力扣第 297 题「 二叉树的序列化与反序列化」就是给你输入一棵二叉树的根节点 ,要求你实现如下一个类:二、前序遍历解法转载 2022-06-05 22:00:06 · 1380 阅读 · 0 评论 -
二叉树(构造篇)
二叉树(纲领篇),先复述一下前文总结的二叉树解题总纲:二叉树的构造问题一般都是使用「分解问题」的思路:构造整棵树 = 根节点 + 构造左子树 + 构造右子树。力扣第 654 题「 最大二叉树」每个二叉树节点都可以认为是一棵子树的根节点,对于根节点,首先要做的当然是把想办法把自己先构造出来,然后想办法构造自己的左右子树。所以,我们要遍历数组把找到最大值 ,从而把根节点 做出来,然后对 左边的数组和右边的数组进行递归构建,作为 的左右子树。通过前序和中序遍历结果构造二叉树力扣第 105 题「 从前转载 2022-06-05 20:52:35 · 5627 阅读 · 0 评论 -
二叉树(思路篇)
承接二叉树(纲领篇),先复述一下前文总结的二叉树解题总纲:本文就以几道比较简单的题目为例,带你实践运用这几条总纲,理解「遍历」的思维和「分解问题」的思维有何区别和联系。力扣第 226 题「 翻转二叉树」不难发现,只要把二叉树上的每一个节点的左右子节点进行交换,最后的结果就是完全翻转之后的二叉树。那么现在开始在心中默念二叉树解题总纲:1、这题能不能用「遍历」的思维模式解决?可以,我写一个 traverse 函数遍历每个节点,让每个节点的左右子节点颠倒过来就行了。单独抽出一个节点,需要让它做什么?让它把自己转载 2022-06-04 17:46:13 · 401 阅读 · 0 评论 -
二叉树(纲领篇)
先在开头总结一下,二叉树解题的思维模式分两类:无论使用哪种思维模式,你都需要思考:如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序位置)做?其他的节点不用你操心,递归函数会帮你在所有节点上执行相同的操作。举个例子,比如两个经典排序算法 快速排序 和 归并排序,对于它俩,你有什么理解?如果你告诉我,快速排序就是个二叉树的前序遍历,归并排序就是个二叉树的后序遍历,那么我就知道你是个算法高手了。为什么快速排序和归并排序能和二叉树扯上关系?我们来简单分析一下他们的算法思想和代码框架:快速排转载 2022-06-04 15:05:38 · 267 阅读 · 0 评论 -
常数时间删除/查找数组中的任意元素
文章目录实现随机集合避开黑名单的随机数实现随机集合这是力扣第 380 题「 常数时间插入、删除和获取随机元素」,看下题目:就是让我们实现如下一个类:class RandomizedSet {public: /** 如果 val 不存在集合中,则插入并返回 true,否则直接返回 false */ bool insert(int val) {} /** 如果 val 在集合中,则删除并返回 true,否则直接返回 false */ bool remove原创 2022-05-28 20:29:08 · 186 阅读 · 0 评论 -
什么时候运用二分搜索
文章目录原始的二分搜索代码二分搜索问题的泛化运用二分搜索的套路框架在二分搜索算法框架解析中,详细介绍了二分搜索的细节问题,探讨了「搜索一个元素」,「搜索左侧边界」,「搜索右侧边界」这三个情况,教你如何写出正确无 bug 的二分搜索算法。但是前文总结的二分搜索代码框架仅仅局限于「在有序数组中搜索指定元素」这个基本场景,具体的算法问题没有这么直接,可能你都很难看出这个问题能够用到二分搜索。所以本文就来总结一套二分搜索算法运用的框架套路,帮你在遇到二分搜索算法相关的实际问题时,能够有条理地思考分析,步步为营原创 2022-05-25 22:06:02 · 230 阅读 · 0 评论 -
数组——二维数组的花式遍历技巧
文章目录顺/逆时针旋转矩阵矩阵的螺旋遍历顺/逆时针旋转矩阵对二维数组进行旋转是常见的笔试题,力扣第 48 题「 旋转图像」就是很经典的一道:题目很好理解,就是让你将一个二维矩阵顺时针旋转 90 度,难点在于要「原地」修改在讲巧妙解法之前,我们先看另一道谷歌曾经考过的算法题热热身:给你一个包含若干单词和空格的字符串 s,请你写一个算法,原地反转所有单词的顺序。比如说,给你输入这样一个字符串:s = "hello world labuladong"你的算法需要原地反转这个字符串中的单词顺序:原创 2022-05-24 20:25:46 · 473 阅读 · 1 评论 -
数组——小而美的算法技巧:差分数组
文章目录算法实践本文讲一个和前缀和思想非常类似的算法技巧「差分数组」,差分数组的主要适用场景是频繁对原始数组的某个区间的元素进行增减。比如说,我给你输入一个数组 nums,然后又要求给区间 nums[2..6] 全部加 1,再给 nums[3..9] 全部减 3,再给 nums[0..4] 全部加 2,再给…一通操作猛如虎,然后问你,最后 nums 数组的值是什么?常规的思路很容易,你让我给区间 nums[i..j] 加上 val,那我就一个 for 循环给它们都加上呗,还能咋样?这种思路的时间复杂转载 2022-05-24 17:29:33 · 350 阅读 · 0 评论 -
数组——小而美的算法技巧:前缀和数组
文章目录一维数组中的前缀和二维矩阵中的前缀和前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和。一维数组中的前缀和力扣第 303 题「 区域和检索 - 数组不可变」,让你计算数组区间内元素的和,这是一道标准的前缀和问题:class NumArray { private int[] sum; public NumArray(int[] nums) { if(nums.length==1) sum=nums; sum=new int[nums.le转载 2022-05-24 16:56:02 · 152 阅读 · 0 评论 -
数组——双指针技巧秒杀七道数组题目
文章目录一、快慢指针技巧一、快慢指针技巧力扣第 26 题「 删除有序数组中的重复项」,让你在有序数组去重:高效解决这道题就要用到快慢指针技巧:我们让慢指针 slow 走在后面,快指针 fast 走在前面探路,找到一个不重复的元素就赋值给 slow 并让 slow 前进一步。这样,就保证了 nums[0..slow] 都是无重复的元素,当 fast 指针遍历完整个数组 nums 后,nums[0..slow] 就是整个数组去重之后的结果。class Solution { public i转载 2022-05-23 21:57:15 · 185 阅读 · 0 评论 -
链表——递归魔法:反转单链表
文章目录一、递归反转整个链表二、反转链表前 N 个节点三、反转链表的一部分一、递归反转整个链表力扣第 206 题「 反转链表」迭代:class Solution { public ListNode reverseList(ListNode head) { ListNode pre=head; ListNode post=null; while(pre!=null){ head=pre;转载 2022-05-19 23:07:33 · 638 阅读 · 0 评论 -
一个方法团灭 LeetCode 股票买卖问题
文章目录一、穷举框架二、状态转移框架这篇文章参考 英文版高赞题解 的思路,用状态机的技巧来解决,可以全部提交通过。不要觉得这个名词高大上,文学词汇而已,实际上就是 DP table,看一眼就明白了。一、穷举框架动态规划核心套路 说过,动态规划算法本质上就是穷举「状态」,然后在「选择」中选择最优解。我们只需要抽出来力扣第 188 题「 买卖股票的最佳时机 IV」进行研究,因为这道题是最泛化的形式,其他的问题都是这个形式的简化,看下题目:那么对于这道题,我们具体到每一天,看看总共有几种可能的「状态」,原创 2022-05-18 22:46:08 · 221 阅读 · 0 评论 -
滑动窗口算法框架解析
文章目录一、最小覆盖子串算法的大致逻辑如下:int left = 0, right = 0;while (right < s.size()) { // 增大窗口 window.add(s[right]); right++; while (window needs shrink) { // 缩小窗口 window.remove(s[left]); left++; }}这个算法技巧的时间复杂度是转载 2022-05-17 17:36:51 · 289 阅读 · 0 评论 -
二分搜索算法框架解析
文章目录一、寻找一个数(基本的二分搜索)二、寻找左侧边界的二分搜索三、寻找右侧边界的二分查找总结一、寻找一个数(基本的二分搜索)这个场景是最简单的,可能也是大家最熟悉的,即搜索一个数,如果存在,返回其索引,否则返回 -1。int binarySearch(int[] nums, int target) { int left = 0; int right = nums.length - 1; // 注意 while(left <= right) { in转载 2022-05-15 22:49:46 · 171 阅读 · 0 评论 -
链表——双指针技巧秒杀七道链表题目
文章目录合并两个有序链表合并 k 个有序链表合并两个有序链表ListNode mergeTwoLists(ListNode l1, ListNode l2) { // 虚拟头结点 ListNode dummy = new ListNode(-1), p = dummy; ListNode p1 = l1, p2 = l2; while (p1 != null && p2 != null) { // 比较 p1 和 p2 两转载 2022-05-15 17:15:46 · 171 阅读 · 0 评论 -
二叉堆详解实现优先级队列
文章目录一、二叉堆概览二、优先级队列概览三、实现 swim 和 sink四、实现 delMax 和 insert二叉堆(Binary Heap)没什么神秘,性质比二叉搜索树 BST 还简单。其主要操作就两个,sink(下沉)和 swim(上浮),用以维护二叉堆的性质。其主要应用有两个,首先是一种排序方法「堆排序」,第二是一种很有用的数据结构「优先级队列」。一、二叉堆概览首先,二叉堆和二叉树有啥关系呢,为什么人们总是把二叉堆画成一棵二叉树?因为,二叉堆在逻辑上其实是一种特殊的二叉树(完全二叉树),只不转载 2022-05-14 12:41:33 · 229 阅读 · 0 评论 -
回溯算法秒杀所有排列/组合/子集问题
文章目录子集(元素无重不可复选)组合(元素无重不可复选)排列(元素无重不可复选)子集/组合(元素可重不可复选)子集组合排列(元素可重不可复选)无论是排列、组合还是子集问题,简单说无非就是让你从序列 nums 中以给定规则取若干元素,主要有以下几种变体:元素无重不可复选,即 nums 中的元素都是唯一的,每个元素最多只能被使用一次,这也是最基本的形式。以组合为例,如果输入 nums = [2,3,6,7],和为 7 的组合应该只有 [7]。元素可重不可复选,即 nums 中的元素可以存在重复,每个元转载 2022-05-14 11:04:59 · 280 阅读 · 0 评论 -
BFS 算法解题套路框架
文章目录一. 算法框架二. 二叉树的最小高度三、解开密码锁的最少次数四、双向 BFS 优化BFS的核心思想就是把一些问题抽象成图,从一个点开始,向周围扩散。一般来说,我们写 BFS 算法都是用「队列」这种数据结构,每次将一个节点周围的所有节点加入队列。BFS 相对 DFS 的最主要的区别是:BFS 找到的路径一定是最短的,但代价就是空间复杂度可能比 DFS 大很多一. 算法框架问题的本质就是让你在一幅「图」中找到从起点 start 到终点 target 的最近距离这个广义的描述可以有各种变体,比如转载 2022-05-12 21:53:40 · 322 阅读 · 0 评论 -
动态规划总结
文章目录适用情况思路流程适用情况问题需要求最优解最优子结构:大问题可以分解为子问题,子问题间必须互相独立,并且大问题的最优解可以由子问题的最优解推导而得重叠子问题:一个子问题需要被重复求解思路流程确定base case:即最小的子问题,可以直接求解得到。确定【状态】,即大问题和子问题中会变化的变量是什么确定【选择】【状态转移方程】,也就是导致【状态】产生变化的行为明确 dp 函数/数组的定义。我们这里讲的是自顶向下的解法,所以会有一个递归的 dp 函数,一般来说函数的参数就是状态转移原创 2022-05-11 10:44:34 · 154 阅读 · 0 评论 -
回溯(DFS)算法解题框架
文章目录回溯法的一般框架使用剪枝函数的深度优先生成状态空间树中结点的求解方法称为回溯法(backtracking);广度优先生成结点,并使用剪枝函数的方法称为分支限界法(branch-and-bound)回溯法的一般框架递归形式void backtrack(int t){//t为当前扩展结点在解空间树中的深度 if(t>n) output(x);//已搜索至叶节点,得到可行解x else{ for(int i=f(n,t);i<=g(n,t);i++){//f(n,t)为未搜索原创 2021-12-14 18:53:22 · 1480 阅读 · 0 评论 -
java刷题
文章目录二叉树层次遍历模板若不需要确定遍历到那一层了:若需要确定到哪一层了按之字形顺序打印二叉树二叉树层次遍历模板若不需要确定遍历到那一层了:伪代码,不仅可用于二叉树,可针对所有用BFS解题。void bfs(){ vis[]={0}; queue<int> pq(start_val); while(!pq.empty()){ int cur =pq.pop(); for(遍历cur所有的相邻节点next){ if(next节点有效&&vis[next原创 2021-11-24 09:46:28 · 283 阅读 · 0 评论 -
经典树结构——B+树的原理及实现
文章目录B+树的概念B+树实现B+树节点参数B+树插入实现B+树删除实现B+树的概念规则:B+跟B树不同B+树的非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针非叶子节点的子节点数=关键字数(来源百度百科)(Mysql 的B+树)B+树相比原创 2021-11-19 15:57:49 · 31174 阅读 · 2 评论 -
经典树结构——B树的原理及实现
B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径不只两个),数据库索引技术里大量使用者B树和B+树的数据结构文章目录B树的意义B树的规则B树的查询流程B Tree的插入B树的意义系统从磁盘读取数据到内存时是以磁盘块(block)为基本单位的,位于同一个磁盘块中的数据会被一次性读取出来,而不是需要什么取什么。此功能叫磁盘预读。二叉树需要加载到内存的,如果二叉树的节点少,没有什么问题,但是如果二叉树的节点很多上亿,由于二叉树每个节点只能存储一个值则会导致在构建二叉树时,需要原创 2021-11-19 15:08:02 · 1741 阅读 · 0 评论 -
经典树结构-红黑树
转载自“教你初步了解红黑树”算法导论上对红黑树的评价:红黑树,一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。文章目录二叉查找树二叉树的插入红黑树红黑树的5个性质:树的旋转知识红黑树的插入和插入修复二叉查找树二叉查找树,也称有序二叉树(ordered binary tree),或已排序二叉树(sorted binary tree),是指一棵空树转载 2021-11-17 20:31:09 · 122 阅读 · 0 评论 -
经典树结构
经典树结构二叉查找树平衡二叉树B-树B+树转载 2021-11-08 20:22:14 · 97 阅读 · 0 评论