自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(334)
  • 问答 (1)
  • 收藏
  • 关注

原创 Unity的二叉堆优先队列

【代码】Unity的二叉堆优先队列。

2025-04-01 13:22:26 67

原创 【蓝桥-2017国赛】【二分】6.区间位移

【代码】【蓝桥-2017国赛】【二分】6.区间位移。

2025-02-27 19:57:31 190

原创 【蓝桥-2017国赛】【并查集】5.合根植物

【代码】【蓝桥-2017国赛】【并查集】5.合根植物。

2025-02-26 17:25:36 146

原创 【蓝桥-2017国赛】4.分考场

【代码】【蓝桥-2017国赛】4.分考场。

2025-02-25 22:11:37 184

原创 【蓝桥】【二分】18.分巧克力

使用二分法,令下界为1,令上界为巧克力的最大值。这里需要注意的就是在二分的时候,我们要定义一个max来记录满足check的最大的数是多少,如果最后直接返回mid的话,可能会导致即使该mid不满足check函数为true的情况下被返回。

2025-02-25 13:07:26 139

原创 【蓝桥杯】1.k倍区间

有人可能会不清楚cnt的作用,我们可以想想当i < j的时候,a[i]和a[j]如果除以m后余数相同,是不是可以说明从i+1到j这一段区间除以m是整除的?然后知道了这个原理,我们每次遍历的时候知道了前缀和a[j]是多少,那么我们就只需要找到有多少个a[i]除以m的余数和a[j]除以m的余数相同,然后统计到res中。然后在最后再将自身加到cnt[a[i] % m]中。还有一点需要注意,cnt[0]需要初始化为1,这是因为如果余数为0,那么就说明a[j]自身可以被m整除。

2025-02-24 20:39:59 325

原创 【贪心】力扣765. 情侣牵手

人和座位由一个整数数组 row 表示,其中 row[i] 是坐在第 i 个座位上的人的 ID。情侣们按顺序编号,第一对是 (0, 1),第二对是 (2, 3),以此类推,最后一对是 (2n-2, 2n-1)。官解使用的是并查集方法,但贪心更加简单高效,将情侣编号变成一样,然后开始两两遍历row,如果row[i]和row[i+1]编号不一样,就去后面的row查找与row[i]相同的编号,然后调换顺序。解释: 只需要交换row[1]和row[2]的位置即可。输入: row = [0,2,1,3]

2025-02-24 09:07:40 224

原创 【数据结构-并查集】力扣1722. 执行交换操作后的最小汉明距离

输入:source = [5,1,2,4,3], target = [1,5,4,2,3], allowedSwaps = [[0,4],[4,2],[1,3],[1,4]]我们定义哈希表sourceCount来记录该集合下source中元素数量。输入:source = [1,2,3,4], target = [2,1,4,5], allowedSwaps = [[0,1],[2,3]]输入:source = [1,2,3,4], target = [1,3,2,4], allowedSwaps = []

2025-02-23 12:17:16 509

原创 【数据结构-并查集】力扣1061. 按字典序排列最小的等效字符串

解释:我们可以把 A 和 B 中的等价字符分为 [a,o,e,r,s,c], [l,p], [g,t] 和 [d,m] 共 4 组,因此 S 中除了 ‘u’ 和 ‘d’ 之外的所有字母都转化成了 ‘a’,最后答案为 “aauaaaaada”。例如, s1 = “abc” 和 s2 = “cde” 的等价信息和之前的例子一样,那么 baseStr = “eed” , “acd” 或 “aab”,这三个字符串都是等价的,而 “aab” 是 baseStr 的按字典序最小的等价字符串。

2025-02-22 19:27:43 420

原创 【数据结构-并查集】力扣1202. 交换字符串中的元素

那么在计算res的时候,遍历字符串s,i=0所在连通集b是字典序最小字符,那么就将b推入res中,然后i=1所在连通集a是字典序最小的字符,将a推入到res中,再遍历到i=2,此时该连通集的小根堆中只剩下了c,那么只能推入c到res中,最后i=3,此时该连通集中的小根堆只剩下了d,推入d到res中,最后输出:“bacd”。输入:s = “dcab”, pairs = [[0,3],[1,2],[0,2]]输入:s = “cba”, pairs = [[0,1],[1,2]]s 中只含有小写英文字母。

2025-02-19 04:07:56 530

原创 【数据结构-并查集】力扣721. 账户合并

输入:accounts = [[“John”, “johnsmith@mail.com”, “john00@mail.com”], [“John”, “johnnybravo@mail.com”], [“John”, “johnsmith@mail.com”, “john_newyork@mail.com”], [“Mary”, “mary@mail.com”]]接下来再次遍历每个账户的邮箱,我们通过unite函数,将parent中各个email对于的index的父节点都指向他们的代表节点。

2025-02-16 17:59:03 742

原创 【数据结构-并查集】力扣990. 等式方程的可满足性

其中 n 是 equations 中的方程数量,C 是变量的总数,在本题中变量都是小写字母,即 C≤26。给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程 equations[i] 的长度为 4,并采用两种不同的形式之一:“a==b” 或 “a!解释:如果我们指定,a = 1 且 b = 1,那么可以满足第一个方程,但无法满足第二个方程。而函数unite的意义就是,将两个集合的根节点,合并成一个根节点,最后该集合的所有节点使用find都会查找到相同的根节点。输入:[“a==b”,“b!

2025-02-15 18:20:54 319

原创 【数据结构-异或字典树】力扣421. 数组中两个数的最大异或值

我们使用贪心的思想,我们要让他异或的值最大,那么就要优先在较高的bit位上找出与nums[j]对应比特位相反数值的路径。也就是说在某个比特位上,nums[j]的该比特位是1,也就是代表树中的right,那么我们就要优先走0,也就是left这条路径。只要与nums[j]某比特位相反的节点存在,那么我们就走该子树的路径,由于该比特位会是异或,所以我们的异或值x就要更新为。输入:nums = [14,70,53,83,49,91,36,80,92,51,66,70]

2025-02-10 17:02:13 303

原创 【数据结构-Tire树】力扣1268. 搜索推荐系统

输出:[[“baggage”,“bags”,“banner”],[“baggage”,“bags”,“banner”],[“baggage”,“bags”],[“bags”]]输入:products = [“mobile”,“mouse”,“moneypot”,“monitor”,“mousepad”], searchWord = “mouse”输出:[[“havana”],[“havana”],[“havana”],[“havana”],[“havana”],[“havana”]]

2025-02-10 15:15:21 1080

原创 【数据结构-Trie树】力扣720. 词典中最长的单词

构造完字典树后,我们从树的根节点开始递归,用longest来记录最长的单词,我们在递归中只有子节点不是空指针,并且子节点的isEnd是true的时候,才会将递归子节点。也就是说,node和wd是在检验没问题后才传入递归函数,而longest需要与当前的单词wd进行比较,如果wd长度更长,则更新longest,如果wd长度等于longest并且字典序更小,也更新longest。输入:words = [“a”, “banana”, “app”, “appl”, “ap”, “apply”, “apple”]

2025-02-06 17:38:00 287

原创 【数据结构-Trie树】力扣677. 键值映射

当我们调用sum的时候,会先从字典树的根节点向下寻找到prefix的最后一个字符的节点,如果prefix在字典树中无法查找到,那么就直接返回0。查找到prefix最后一个字符的节点后,我们要开始计算以该节点开始,遍历所有的子节点,当v不为-1的时候,就说明该节点的字符是某个单词的结尾,那么我们就将该单词映射的值v加到search_sum中。int sum(string prefix) 返回所有以该前缀 prefix 开头的键 key 的值的总和。返回具有前缀等于给定字符串的键的值的总和。

2025-02-03 17:05:33 532

原创 【数据结构-Trie树】力扣648. 单词替换

接下来我们自定义一个split函数用来将sentence的单词储存到vector的words中,接下来我们定义一个findPrefix函数,将words中的每一个word在字典树中进行查找,看有没有词根,如果有的话就返回词根,否则返回word自身。在英语中,我们有一个叫做 词根(root) 的概念,可以词根 后面 添加其他一些词组成另一个较长的单词——我们称这个词为 衍生词 (derivative)。由于我们最后要返回的是一个句子,那么我们就将ans中的单词中插入空格,储存到res中,最后返回res即可。

2025-02-03 15:20:15 602

原创 【数据结构-字典树】力扣14. 最长公共前缀

接下来我们从字典树的根节点不断向下查找,我们看他有几个子节点,如果有多个子节点,就说明不需要继续添加字符了,因为只有当children的数量为1个的时候,说明是公共前缀。然后我们还要检查我们选择的下一个节点是不是某个word的结尾,如果是的话,就将其添加到res后,停止继续查找添加。输入:strs = [“flower”,“flow”,“flight”]输入:strs = [“dog”,“racecar”,“car”]如果不存在公共前缀,返回空字符串 “”。解释:输入不存在公共前缀。

2025-02-01 17:46:39 516

原创 【数据结构-字典树】力扣211. 添加与搜索单词 - 数据结构设计

所以当遇到’.‘的时候,我们就遍历当前节点的所有children,也就是代表’.‘被当成了任意一个字符,然后开始遍历。要注意的是在递归的时候,需要调用child->searchHelper,这是因为child代表的是’.‘代替的字符,这样递归的时候node才能指向正确的位置,如果递归返回的是true,那么说明将’.‘替换成child字符是可行的,如果所有替换成任意child都不可行,那么返回false。bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true;

2025-02-01 16:21:48 712

原创 【数据结构-前缀树】力扣208. 实现 Trie (前缀树)

接下来我们查看insert函数,我们一样把要插入的单词拆成一个个字符,如果我们沿着字典树某个路径找不到某个字符,那么就会new一个node->children[ch],并且将node移到新开辟的节点,在插入完最后一个字符的时候,会进行一个标记。是否存在,如果该节点存在的话我们就将node移到该节点,然后我们继续遍历prefix的下一个字符,如果prefix所有字符都能依次在字典树沿着某条路径找到,那么他就会返回prefix的最后一个节点的指针。// 返回 True。

2025-02-01 14:48:03 755

原创 【懒删除堆】力扣3092. 最高频率的 ID

但是由于我们的频率一直在变化,我们为了减少对堆的操作,我们只要检验我们当前回合的id的最大频率,和哈希表中的正确频率是否一样,如果不一样的话,就将它从堆中弹出删除,直到检验成功为止,堆顶的元素才是答案。第 1 步操作后,有 3 个 ID 为 2 的元素和 2 个 ID 为 3 的元素,所以 ans[1] = 3。第 3 步操作后,有 2 个 ID 为 3 的元素和 1 个 ID 为 1 的元素,所以 ans[3] = 2。输入:nums = [2,3,2,1], freq = [3,2,-3,1]

2025-01-31 00:38:14 423

原创 【懒删除堆】力扣2349. 设计数字容器系统

我们再定义一个哈希表,可以通过烹饪方式,然后映射到一个堆,pair的first是评分,second是food的名字。我们这个堆要使用最小堆,这是因为在评分一样的时候,最小堆会按字典序来排序food的名字,所以我们的评分在这个哈希表中要加上负号。int find(int number) 返回给定数字 number 在系统中的最小下标。// 数字 10 所在的下标为 1 ,2 ,3 和 5。// 容器中下标为 2 处填入数字 10。// 容器中下标为 1 处填入数字 10。

2025-01-30 22:55:36 431

原创 【懒删除堆】力扣2349. 设计数字容器系统

int find(int number) 返回给定数字 number 在系统中的最小下标。// 容器中下标为 1 处填入数字 20。注意,下标 1 处之前为 10 ,现在被替换为 20。// 数字 10 所在的下标为 1 ,2 ,3 和 5。// 数字 10 所在下标为 2 ,3 和 5。// 容器中下标为 2 处填入数字 10。// 容器中下标为 1 处填入数字 10。// 容器中下标为 3 处填入数字 10。// 容器中下标为 5 处填入数字 10。

2025-01-30 00:14:06 317

原创 【反悔堆】【hard】力扣871. 最低加油次数

我们遍历每个经过的加油站以及终点,我们用curr和prev来记录相邻两个地方之间的距离,如果油够经过这段距离,我们就不用进行操作,只要将当前加油站油的数量加入到优先队列q中即可。如果油不够经过这段距离,那么我们就需要在之前的加油站进行加油,我们优先在有最多油的加油站加油,也就是q.top(),并且记录ans,直到油够经过这段距离位置。输入:target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]]地,则返回 -1。

2025-01-28 23:00:20 500

原创 【反悔堆】【hard】力扣630. 课程表 III

那么在上一个课程中,m + n是小于上一个课程的结束时间的,由于我们将m替换成比m小的当前课程的天数,而当前课程的结束时间又大于上一个课程的结束时间,所以替换后,一定可以保证不会超过当前课程的结束天数。输入:courses = [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]]第二,修第 3 门课,耗费 1000 天,在第 1100 天完成,在第 1101 天开始下门课程。你的学期从第 1 天开始。输入:courses = [[3,2],[4,3]]

2025-01-28 17:49:03 460

原创 【反悔堆】力扣1642. 可以到达的最远建筑

我们模拟从建筑1向建筑n移动,当出现前面建筑更高的时候,就将deltaH放到最小堆q中,如果最小堆里元素数量大于梯子数量,那么我们就弹出最小高差来使用砖块,以保证最高差都是用梯子。输入:heights = [4,12,2,7,3,18,20,3,19], bricks = 10, ladders = 2。输入:heights = [4,2,7,6,9,14,12], bricks = 5, ladders = 1。你从建筑物 0 开始旅程,不断向后面的建筑物移动,期间可能会用到砖块或梯子。

2025-01-27 20:35:21 575

原创 【反悔堆】力扣LCP 30. 魔塔游戏

如果当前房间是怪物房间,则将它放到堆中,我们如果受到当前房间效果后生命值不为正,那么就说明我们要将之前的最大怪物伤害的房间放到末尾,所以我们就将最小堆堆顶的值加到hp上,并且ans++代表我们进行了一次调整,然后用delay来储存我们调整到末尾的伤害是多少。当遍历完成后,如果hp += delay不为正数,那么返回-1,否则返回ans。假定小扣原计划按房间编号升序访问所有房间补血/打怪,为保证血量始终为正值,小扣需对房间访问顺序进行调整,每次仅能将一个怪物房间(负数的房间)调整至访问顺序末尾。

2025-01-27 19:59:49 902

原创 【二分查找】力扣373. 查找和最小的 K 对数字

nums1[0] + nums2[0]是两个数组元素和的最小值,组成二分下界,nums1[m-1] + nums2[n-1]组成二分上界。由于我们最终要返回的是前k小的所有的数组对。请找到和最小的 k 个数对 (u1,v1), (u2,v2) …输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3。输入: nums1 = [1,1,2], nums2 = [1,2,3], k = 2。输出: [1,2],[1,4],[1,6]输出: [1,1],[1,1]

2025-01-26 20:13:14 348

原创 【矩阵二分】力扣378. 有序矩阵中第 K 小的元素

我们可以统计左上部分小于等于8的数的数量,看8在排序后是第几小的数(因为图片有多个8,所以返回的是8是第几小的数的最大情况,即升序排列中最右边的8的位置)。所以在二分查找中,我们从取left + right除以2的值为mid,如果在check函数中得出来左上部分的数量大于等于我们所期待的k,那么就说明我们的取的mid大于等于实际元素,这时候我们就将right = mid,缩小他的上界。输入:matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8。

2025-01-25 16:20:15 1055

原创 【最小堆】【动态规划】力扣264. 丑数 II

我们可以使用堆来模拟丑数的情况,我们定义一个堆,堆顶是最小的数,这个时候我们让堆顶的数乘以factors的三个不同因子的情况,继续加入到堆中,然后将堆顶元素弹出,这个时候堆顶元素就是第二小的数(包含已弹出的最小数),也就是第二个丑数,然后不断继续将堆顶元素乘以factors中顶三个不同因子,得到更多丑数。这时候我们要将他们正确插入到dp中,这时候就找其中最小的数也就是2放到dp[2]中,dp[2]中放的是1x2。那么三者中3最小,所以dp[3]中存放的是1x3=3,这个时候令p3++指向2。

2025-01-24 01:31:00 354

原创 【贪心】力扣1405. 最长快乐字符串

我们可以使用贪心的算法,我们每次都挑选出最多数量的字符,然后看字符串的最后两个字符和这个字符是否一样,如果一样的话就挑选数量第二多的字符,直到找到合适的字符。如果字符串中不含有任何 ‘aaa’,‘bbb’ 或 ‘ccc’ 这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。s 中 最多 有a 个字母 ‘a’、b 个字母 ‘b’、c 个字母 ‘c’。s 中只含有 ‘a’、‘b’ 、‘c’ 三种字母。输入:a = 1, b = 1, c = 7。输入:a = 2, b = 2, c = 1。

2025-01-23 23:52:52 174

原创 【贪心】力扣1953. 你可以工作的最大周数

场景1:m-1>n,即没有足够多的其他任务填充aaaa中的空,所以反过来考虑,将n个其他任务平铺,bbccdd,最多可以在其中插入n+1(左右端点都可以插入)个任务a,由m-1>n知,m>n+1,可以完成目标,此时花费的时间是n+n+1;一旦所有项目中的全部阶段任务都完成,或者执行仅剩的一个阶段任务将会导致你违反上面的规则,你将 停止工作。对于场景2中的情况,我们优先使用阶段最多的任务与阶段第二多的任务交替进行,然后两个任务的阶段数量不断缩减,当。每周,你将会完成 某一个 项目中的 恰好一个 阶段任务。

2025-01-22 19:01:26 261

原创 【数据结构-堆】力扣1054. 距离相等的条形码

请你重新排列这些条形码,使其中任意两个相邻的条形码不能相等。你可以返回任何满足该要求的答案,此题保证存在答案。这道题和力扣767方法一样,只不过这里由于条形码的种类较多,所以我们使用哈希表来存放,具体步骤参考主页力扣767。在一个仓库里,有一排条形码,其中第 i 个条形码为 barcodes[i]。输入:barcodes = [1,1,1,1,2,2,3,3]输入:barcodes = [1,1,1,2,2,2]输出:[1,3,1,3,2,1,2,1]输出:[2,1,2,1,2,1]

2025-01-21 00:42:57 337

原创 【数据结构-堆】力扣767. 重构字符串

接着当s中某个字符的个数大于字符串s长度的一半的时候(s长度如果是奇数则向上取整),那么则无法有重构字符串。接着我们使用贪心的思路,我们每次取出字符数量最多的两个字符,将他们加入到重构字符串new_s中。我们要比较字符数量最多的数量,可以用最大堆来做,cmp是我们自己写的比较函数。每次将最多数量的字符加入到new_s后,将他们数量都减去1,当他们数量还大于0的时候,才将它们继续加入到q中。给定一个字符串s,检查是否能重新排布其中的字母,使得两相邻的字符不同。当q中只剩下一种字符,就加入new_s中。

2025-01-19 18:29:09 302

原创 【贪心】力扣984. 不含 AAA 或 BBB 的字符串

谁多用谁,定义一个字符串ans,当a和b都大于0的时候,如果a的数量比b的数量多,ans就加上aab,如果b数量多,ans就加入bba,如果相同,就推入ab。并且都在更新ans后,更新a和b可使用的次数。当a或者b有一者为0的时候,那么接下来的字符就都是a或者都是b。s的长度为a+b,且正好包含a个‘a’字母与b个‘b’字母;解释:“abb”,“bab”和“bba”都是正确答案。对于给定的a和b,保证存在满足要求的s。输入:a=1,b=2。

2025-01-19 01:36:40 244

原创 【数据结构-堆】力扣1705. 吃苹果的最大数目

有一棵特殊的苹果树,一连n天,每天都可以长出若干个苹果。在第i天,树上会长出apples[i]个苹果,这些苹果将会在days[i]天后(也就是说,第i+days[i]天时)腐烂,变得无法食用。接着我们将新长的苹果加到q中,最后模拟吃掉苹果,将ans加一,然后将q的队头的苹果减少1代表苹果被吃掉。输入:apples=[3,0,0,0,0,2],days=[3,0,0,0,0,2]输入:apples=[1,2,3,5,2],days=[3,2,1,4,2]

2025-01-19 00:49:58 390

原创 【数据结构-堆】【hard】力扣502. IPO

接下来我们进行k次投资遍历,我们知道投资的项目后推入大根堆q中,堆顶就是我们所需要的能投资的最大利润项目,然后进行投资,利润加到w中。这道题我们可以用贪心的思想,当我们有w资本的时候,能完成某些项目的投资,那么由于我们投资的次数有限制,并且投资利润高的项目能使w更大以便能有投资更多项目的权限。总而言之,从给定项目中选择 最多 k 个不同项目的列表,以 最大化最终资本 ,并输出最终可获得的最多资本。输入:k = 2, w = 0, profits = [1,2,3], capital = [0,1,1]

2025-01-18 02:32:53 387

原创 【数据结构-堆】【hard】力扣23. 合并 K 个升序链表

这道题是关于链表的题,题目要求合并k个升序链表,实际上我们就可以有这么一个思路:我们将每个链表的元素都丢入小根堆中,然后将小根堆的元素依次组成一个新的链表。由于题目中已经升序排列好每个链表,也就是说每个链表的头节点的val是链表中最小的。:考虑优先队列中的元素不超过 k 个,那么插入和删除的时间代价为 O(logk),这里最多有 kn 个点,对于每个点都被插入删除各一次,故总的时间代价即渐进时间复杂度为 O(kn×logk)。输入:lists = [[1,4,5],[1,3,4],[2,6]]

2025-01-18 00:17:35 567

原创 【单调栈】力扣1130. 叶值的最小代价生成树

在所有这样的二叉树中,返回每个非叶节点的值的最小可能总和。解释:有两种可能的树,第一种的非叶节点的总和为 36 ,第二种非叶节点的总和为 32。最高效的O(n)做法,从凌晨12点做到凌晨三点半,还是没想通,以后补题解。数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。每个非叶节点的值等于其左子树和右子树中叶节点的最大值的乘积。如果一个节点有 0 个子节点,那么该节点为叶节点。每个节点都有 0 个或是 2 个子节点。输入:arr = [6,2,4]输入:arr = [4,11]

2025-01-17 03:32:32 231

原创 【区间DP】【记忆化搜索】力扣375. 猜数字大小 II

也就是我们在计算dfs(i,j)的时候,我们不断猜测k,我们既要计算出此时选择k的最大支付金额的路径(即运气最差的时候)。我们定义一个ans来记录dfs中最小能保证获胜的支付金额,首先我们先在i到j的范围内不断猜测数字k是多少,然后定义一个cost来代表选择k的时候可能最坏情况,而ans用来表示我们应该选取哪个k可以保证最小的最大支付金额。递推的边界情况是i >= j,因为这个时候i=j,我们可以猜对数字,所以这个时候的开销是0。每当你猜了数字 x 并且猜错了的时候,你需要支付金额为 x 的现金。

2025-01-17 01:36:35 852

空空如也

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

TA关注的人

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