
数据结构与算法
文章平均质量分 55
刷题总结
blogSpaceX
这个作者很懒,什么都没留下…
展开
-
leetcode股票买卖系列题目(动态规划)
最近A股大火,那么收集一下leetcode股票买卖系列题目来刷刷。股票买卖系列题目这类问题都可以用动态规划DP来解决。上述的第二和第三步,合起来就是建立。原创 2024-11-24 12:10:33 · 352 阅读 · 0 评论 -
数据结构可视化网站
Data Structure VisualizationCurrently, we have visualizations for the following data structures and algorithms:原创 2024-10-05 17:43:58 · 895 阅读 · 1 评论 -
钥匙和房间的题解——使用dfs或bfs进行图遍历
这 n 个房间看成有向图中的 n 个节点,在x号房拿到了打开y号房的钥匙,可以看作是图中的 x 号点到 y 号点的一条有向边。这样一来,问题就变成了给定一张有向图,询问从 0 号节点出发是否能够到达所有的节点。原创 2024-09-17 11:35:03 · 377 阅读 · 0 评论 -
分割数组的两种解法:动态规划、二分法
(包括当前子数组),那么每当 sum 加上当前值超过了 cnt,我们就把当前取的值作为新的一段分割子数组的开头,并将 cnt 加 1。遍历结束后验证是否 cnt 不超过 k。本题中,我们注意到:当我们选定一个值 x,我们可以线性地验证是否存在一种分割方案,满足其最大分割子数组和不超过 x。地模拟分割的过程,从前到后遍历数组,用 sum 表示当前分割子数组的和,cnt 表示已经分割出的。「将数组分割为 m 段,求……」是动态规划题目常见的问法。最大值尽可能小」是二分搜索题目常见的问法。原创 2024-03-24 15:24:48 · 294 阅读 · 1 评论 -
Leetcode刷题模版总结
1. 双指针双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。也可以延伸到多个数组的多个指针。1)滑动窗口若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的区域即为当前的窗口),经常用于区间搜索。例题:class Solution {public: int maxVowels(string s, int k) { ...原创 2023-10-06 21:43:00 · 260 阅读 · 0 评论 -
位运算符
位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。练习题:lc191. 位1的个数class Solution { // 开始给的无符号整数一定大于0,所以在while循环中n为true,每次取二进制n的末位,与1进行&运算,结果为1,说明该位为1,那么count++;n往右移一位,并在最左端补0,当把二进制位中1全移走时,n为0,false...原创 2023-02-26 20:23:00 · 68 阅读 · 0 评论 -
动态规划解背包问题(01背包)
一、概念问题可以描述为:给定一组物品(有N 个物品和容量为W 的背包,每个物品都有自己的体积w 和价值v),在限定的总重量内,我们如何选择,才能使得物品的总价格最高。常见的有01背包问题,即限定每种问题只能取0个或1个。问:要使背包装的物品价值最大,应该怎么选,最大值是多少?二、动态规划解法动态规划数组dp[i][j]含义:前i件物品,放入容量为j的背包里的最大价值。递推公式:dp...原创 2023-02-19 18:01:00 · 87 阅读 · 0 评论 -
单调栈
一但要求下一个更大的元素,就是用单调栈解,力扣题库相似的题目都是这个解法。栈(stack)是很简单的一种数据结构,先进后出的逻辑顺序,符合某些问题的特点,比如说函数调用栈。单调栈实际上就是栈,只是利用了一些巧妙的逻辑,使得每次新元素入栈后,栈内的元素都保持有序(单调递增或单调递减)。例题:496. 下一个更大元素 I解法:单调栈 + 哈希表第1个子问题用单调栈解决。倒序遍历num...原创 2023-03-04 20:20:00 · 54 阅读 · 0 评论 -
字典树
一、概念字典树(Trie)用于判断字符串是否存在或者是否具有某种字符串前缀。包含三个单词 "sea","sells","she" 的 Trie 长这样:为什么需要用字典树解决这类问题呢?假如我们有一个储存了近万个单词的字典,即使我们使用哈希,在其中搜索一个单词的实际开销也是非常大的,且无法轻易支持搜索单词前缀。然而由于一个英文单词的长度n 通常在10 以内,如果我们使用字典树,则可以在O...原创 2023-02-19 11:45:00 · 45 阅读 · 0 评论 -
二叉树的遍历——前序、中序、后序
什么是遍历:所谓遍历(Traversal),是指沿着某条搜索路线,依次对树(或图)中每个节点均做一次访问。访问结点所做的操作依赖于具体的应用问题, 具体的访问操作可能是检查节点的值、更新节点的值等。命名根据访问结点操作发生位置命名:① NLR:前序遍历(PreorderTraversal亦称(先序遍历))——访问结点的操作发生在遍历其左右子树之前。② LNR:中序遍历(Inord...原创 2023-02-08 23:38:00 · 303 阅读 · 0 评论 -
刷题常用:递归算法,及递归的底层实现机制
编程语言中,我们习惯将函数调用自身的过程称为递归,调用自身的函数称为递归函数,用递归方式解决问题的算法称为递归算法。设计递归函数时,我们必须为它设置一个结束递归的“出口”,否则函数会一直调用自身(死循环),直至运行崩溃。接下来我们以“用递归方式求 n! ”为例,给大家展示一个正确的递归函数。#include <stdio.h>int factorial(int n) { ...原创 2023-02-08 23:08:00 · 139 阅读 · 0 评论 -
图——拓扑排序
拓扑排序定义给定一个包含 n 个节点的有向图G,我们给出它的节点编号的一种排列,如果满足:对于图 G 中的任意一条有向边 (u, v),u 在排列中都出现在 v 的前面。那么称该排列是图 G 的「拓扑排序」。题目与解析lc 210.课程表 II我们可以将本题建模成一个求拓扑排序的问题了:我们将每一门课看成一个节点;如果想要学习课程 A之前必须完成课程 B,那么我们从 B 到 ...原创 2022-12-18 22:36:00 · 56 阅读 · 0 评论 -
lc542. 01 矩阵 (广度优先搜索、动态规划)
题目:542.01 矩阵题解:一、广度优先搜索如果从每个1出发,广度优先搜索它临近的0,每一次搜索,只能更新当前1的信息,会比较耗时。因此,我们可以从矩阵中的所有0出发,寻找到每个1的距离,这个方法也称多源广度优先搜索。例如:1、从所有的0出发搜索,找到了5个1(浅黄绿色)(距离为1),再从这5个1出发,到达中间1的位置(距离为2)。第一步从超级源点出发,第二步就能到达矩阵中所...原创 2023-01-14 17:48:00 · 148 阅读 · 0 评论 -
快速排序和快速选择算法
快速排序快速排序算法的实现思路是:从待排序序列中任选一个元素(假设为 pivot)作为中间元素,将所有比 pivot 小的元素移动到它的左边,所有比 pivot 大的元素移动到它的右边;(这一步被称为「划分 partition」)pivot 左右两边的子序列看作是两个待排序序列,各自重复执行第一步。直至所有的子序列都不可再分(仅包含 1 个元素或者不包含任何元素),整个序列就变成了一个有...原创 2023-03-19 23:06:00 · 71 阅读 · 0 评论 -
二分图与染色算法
二分图的概念二分图就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集,两个子集内的顶点不相邻。染色法概念二分图算法也称为染色法。如果可以用两种颜色对图中的节点进行着色,并且保证相邻的节点(边两端的节点)颜色不同,那么图为二分。下图中有相邻节点的颜色相同,因此不是二分图。题目与解析lc 785.判断二分图class Sol...原创 2022-12-18 17:51:00 · 61 阅读 · 0 评论 -
二分查找——区间开闭性
具体到代码上,二分查找时区间的左右端取开区间还是闭区间在绝大多数时候都可以,因此有些初学者会容易搞不清楚如何定义区间开闭性。这里我提供两个小诀窍,第一是尝试熟练使用一种写法,比如左闭右开(满足C++、Python 等语言的习惯)或左闭右闭(便于处理边界条件),尽量只保持这一种写法;第二是在刷题时思考如果最后区间只剩下一个数或者两个数,自己的写法是否会陷入死循环,如果某种写法无法跳出死循环,则考虑...原创 2023-03-14 23:32:00 · 309 阅读 · 0 评论 -
从 695. 岛屿的最大面积 入手深度优先搜素DFS
一、什么是深度优先遍历(DFS)以“深度”为第一关键词,每次都沿路径到不能再前进时,才退回到最近的岔路口,然后继续按同样的逻辑搜索。二、题目与解答题目:Leetcode 695.岛屿的最大面积解答思路:首先要遍历数组,当发现(i,j)对应为陆地时,进行如下步骤:(1)递归解法递归解法最重要的是首先要确定递归边界。(设计递归函数时,我们必须为它设置一个结束递归的“出口”,否则函...原创 2022-12-10 21:44:00 · 70 阅读 · 0 评论 -
leetcode题中的逆向思维——集锦
417. 太平洋大西洋水流问题虽然题目要求的是满足向下流能到达两个大洋的位置,如果我们对所有的位置进行搜索,那么在不剪枝的情况下复杂度会很高。因此我们可以反过来想,从两个大洋开始向上流,这样我们只需要对矩形四条边进行搜索。搜索完成后,只需遍历一遍矩阵,满足条件的位置即为两个大洋向上流都能到达的位置。...原创 2023-04-02 21:34:00 · 292 阅读 · 0 评论 -
桶排序
leetcode347. 前 K 个高频元素顾名思义,桶排序的意思是为每个值设立一个桶,桶内记录这个值出现的次数(或其它属性),然后对桶进行排序。红色代表频率。最后,我们从后往前遍历,直到找到k个旧桶。class Solution {public: vector<int> topKFrequent(vector<int>& nums, ...原创 2023-04-01 11:47:00 · 53 阅读 · 0 评论 -
分治(Divide and Conquer)算法之归并排序
顾名思义,分治问题由“分”(divide)和“治”(conquer)两部分组成,通过把原问题分为子问题,再将子问题进行处理合并,从而实现对原问题的求解。我们在排序章节展示的归并排序就是典型的分治问题,其中“分”即为把大数组平均分成两个小数组,通过递归实现,最终我们会得到多个长度为1 的子数组;“治”即为把已经排好序的两个小数组合成为一个排好序的大数组,从长度为1 的子数组开始,最终合成一个大数组...原创 2023-04-02 23:32:00 · 94 阅读 · 0 评论 -
哈希表——解205. 同构字符串及290. 单词规律
205. 同构字符串此题是「290. 单词规律」的简化版,需要我们判断 s 和 t 每个位置上的字符是否都一一对应,即 s 的任意一个字符被 t 中唯一的字符对应,同时 t 的任意一个字符被 s 中唯一的字符对应。这也被称为「双射」的关系。以示例 2为例,t 中的字符 a 和 r虽然有唯一的映射 o,但对于 s 中的字符 o 来说其存在两个映射 {a,r},故不满足条件。因此,我们维护两...原创 2023-08-20 18:00:00 · 70 阅读 · 0 评论 -
吃透单调栈(2)——解两道Hard题:接雨水、柱状图中最大的矩形问题
怎么想到要用单调栈的?这类题目的数据通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置(寻找边界),此时我们就要想到可以用单调栈了。42.接雨水这道题就是要求解每一个柱子左边第一个比它高的柱子,以及右边第一个比它高的柱子,然后这两个柱子间形成的凹槽面积。注意,是横向扫来求面积。比如下图,4号柱左边第一个比它高的柱子是3号,右边第一个比它高的是7号,面积是蓝色...原创 2023-09-03 15:55:00 · 110 阅读 · 0 评论 -
分治算法——241. 为运算表达式设计优先级
分治思路:对于一个算式来说,总是可以根据运算符分为左右两部分算式,接着分别计算结果并合并;每一个结果都是一个数组,包含这个算式的所有可能结果,计算时将左右两部分排列组合;递归的终点是字符串是纯数字(即分到一个算式中只剩下一个数字),直接返回。比如示例中的2*3-4*5,有下面的分法:1、分为2与3-4*5,对于3-4*5,继续细分 3-4*5可以分为3与4*5,或者3-4与5,所以结果...原创 2023-08-13 14:31:00 · 75 阅读 · 0 评论 -
吃透单调栈(1)——单调栈入门
单调栈是一种理解起来很容易,但是运用起来并不那么简单的数据结构。一句话解释单调栈,就是一个栈,里面的元素的大小按照他们所在栈内的位置,满足一定的单调性。单调栈摸版下面维护一个顶大底小的的单调栈(单调递减栈)stack<int> st;for(int i = 0; i < nums.size(); i++){ while(!st.empty() &&a...原创 2023-09-03 10:56:00 · 104 阅读 · 0 评论 -
Leetcode刷题本地debug框架搭建
思路1. 初版cmake + 单一.cpp文件参考:https://blog.songjiahao.com/archives/3622. 改良版cmake + 源文件、头文件(含List、Tree等数据结构)分离 + gtest参考:https://github.com/Pokerpoke/LeetCodeNormal模板以Leetcode 1 两数之和 为例#include...原创 2023-09-10 16:28:00 · 640 阅读 · 0 评论 -
广度优先搜索(BFS)应用——层序遍历和最段路径
BFS模板:BFS使用队列,把每个还没有搜索到的点依次放入队列,然后再弹出队列的头部元素当做当前遍历点。BFS总共有两个模板:模板1:如果不需要确定当前遍历到了哪一层,BFS模板如下。 1 while queue 不空: 2 cur = queue.pop() // 弹出队列的头部元素当做当前遍历点 3 for 节点 in cur的所有相邻节点: 4 ...原创 2022-12-03 17:45:00 · 198 阅读 · 0 评论 -
验证二叉搜索树——采用中序遍历解决
在做98.验证二叉搜索树时,解决思路是中序遍历,判断当前节点是否大于中序遍历的前一个节点,如果大于,说明满足 BST,继续遍历;否则直接返回 false。下面是中序遍历的非递归实现,借助了栈结构:...原创 2022-10-27 23:59:00 · 65 阅读 · 0 评论 -
玩转双指针
一、算法简介双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。也可以延伸到多个数组的多个指针。若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的区域即为当前的窗口),经常用于区间搜索。若两个指针指向同一数组,但是遍历方向相反,则可以用来进行搜索,待搜索的数组往往是排好序的。二、指针小知识对于C++ 语言,指针还可以玩出很多新的花样。一些常见...原创 2022-12-04 11:54:00 · 71 阅读 · 0 评论 -
从《打家劫舍》入门动态规划
一、入门动态规划的的四个解题步骤是:定义子问题写出子问题的递推关系确定 DP 数组的计算顺序 (DP 数组也可以叫”子问题数组”,因为 DP 数组中的每一个元素都对应一个子问题。)空间优化(可选)class Solution {public: int rob(vector<int>& nums) { // 子问题f(k):从k间房中...原创 2022-12-01 23:57:00 · 53 阅读 · 0 评论