![](https://img-blog.csdnimg.cn/20201014180756926.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法
空、白、
NO GAME NO LIFE
展开
-
【学习总结】在Unity中用C#写一棵红黑树
红黑树作为基本的二叉查找数据结构,大概是属于游戏客户端这边必须知道的东西。所以一不做二不休,干脆手写一个出来。参考文章或视频:红黑树原理和算法详细介绍红黑树详解首先需要知道的是红黑树的特性:红黑树的每一个节点都必须是红色或者是黑色红黑树的根节点一定是黑色的每个叶子节点(这里指的是NULL的那些节点)是黑色如果一个节点是红色的,则其子节点一定是黑色的,即不存在两个连续的红色节点从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点与AVL树相同,红黑树由于也是一棵平衡二叉树,所以原创 2021-09-14 13:21:00 · 614 阅读 · 0 评论 -
【算法可视化-Unity】A*寻路算法
开新坑了开新坑了~(这应该是个长期坑,现在的想法是把学过的或者有点难度的算法都做一个可视化)正如标题所说的那样,现在我打算来做一个算法的可视化,除了帮助自己更好的理解算法之外,也帮助其它小伙伴们更好的理解。那么话不多说,进入今天的主角,A*寻路算法。A*寻路算法的核心原理说起来十分简单:每一次都选择综合代价最小的格子,以此实现一定方向的遍历算法的具体实现思路也很简单:整个代码部分是我自己编写的,就一个脚本,注释十分详细,但同时也有很多问题(结构有点冗余,而且有个重载操作符的问题还没解决)现原创 2021-08-20 18:52:47 · 586 阅读 · 0 评论 -
【LeetCode刷题笔记】46.全排(DFS与库函数)
题目:其实这题的核心思想和上一题是一样的(78.子集),只不过呢这道题不需要从最短开始考虑,每一次考虑的都是最长数组,因此需要使用for循环。另外,还有一个原因,C++其实是有全排列函数的,没想到吧!next_permutation(),求该数组或者向量的字典序的下一位所以使用之前需要排序思路也很简单,就是每次先固定去交换一位,然后进一步遍历,遍历完之后再换回来进入下一个循环(固定交换下一位数)C++代码如下(这次我觉得我的比官方简洁):class Solution {public:原创 2021-08-01 17:50:10 · 111 阅读 · 0 评论 -
【LeetCode刷题笔记】78.子集(DFS板子题)
题目:好久没有刷题了,今天遇到了板子题都还想了一会,秋招是不是可以预先说GG了。hhhh这种类型题目的通解就是DFS,某种程度上来说也是暴力的一种,这里附上板子,基本上所有的DFS的类型都可以按照这个板子来做,包括矩阵(可能涉及到一个方向选择的问题)vector<int> t;void dfs(int cur, int n) { if (cur == n) { // 记录答案 // ... return; } //原创 2021-08-01 16:40:00 · 345 阅读 · 0 评论 -
【LeetCode刷题笔记】567.字符串的排列
题目:今天这题记录一下的原因有两点:第一:忘了Vector之间重载了方法,可以直接用==和!=比较第二:没想到两个子串长度应该是相等的,导致第一版代码十分臃肿思路:1.这题很容易可以想到是使用滑动窗口,对一定范围的内S2的子序列进行统计字符个数与S1进行比较。2.其中窗口的大小应该设定为S1的长度3.每当一个窗口不符合要求的时候就往下滑动一格,对窗口字符统计数组做相应处理。C++代码(附带测试)#include<iostream>#include<vector>原创 2021-07-25 15:20:29 · 76 阅读 · 0 评论 -
【LeetCode刷题笔记-167.两数之和Ⅱ】
今天这题记录一下是因为没有想到双指针的解法。第一种:很自然就能想到,遍历数组中的每一个数字,然后去寻找另一个。因此可以用for循环固定+二分查找的办法做。代码:class Solution {public: vector<int> twoSum(vector<int>& numbers, int target) { vector<int> ans; for(int i=0;i<numbers.size().原创 2021-07-15 09:22:35 · 80 阅读 · 0 评论 -
【LeetCode刷题笔记-977.有序数组的平方】
今天这题有点意思,所以记录一下暴力的想法自然是先遍历一遍数组然后再排序,但是这样会超时,因为时间复杂度还是比较高。因此需要别的方案。由于要按照非递减排序,我们很自然就能想到,平方最大值产生的位置是数组的末尾或者是队首。因此,使用双指针移动遍历数组,每次都进行平方判断,将较大的那个数加入新数组的末尾。最后返回即可。代码:(C++附带测试)#include<iostream>#include<vector>#include<algorithm>#include.原创 2021-07-14 09:29:47 · 88 阅读 · 0 评论 -
【LeetCode刷题笔记645:错误的集合】
题目:今天这题思路上来就有了,要么排序逐一比对,要么哈希表记录,两种都可以。另外,今天虽然是排序1~n的整数,但是不能使用直接挪动到相应位置上的办法,因为那样虽然可以找出重复的数字,但是无法找出缺少的数字。排序:class Solution {public: vector<int> findErrorNums(vector<int>& nums) { vector<int> errorNums(2); int n原创 2021-07-04 10:48:16 · 99 阅读 · 0 评论 -
【LeetCode刷题笔记:451.根据字符出现频率排序】
题目:今天这题的思路算是比较简单的,遍历一遍得到每个字符出现的数量,然后根据数量大小排序直接替换string字符即可。但是,写这题的时候没注意看下面的测试用例还有大写字母,所以一开始就按照全小写字母的方式去建立了一个26X2的二维数组,用于统计数量导致出错。优化方法也很简单,既然多了大写字母,那么为了避免额外的一些开销,我们这里还是使用哈希表比较好。因此,思路就变为:我们使用哈希表去存储每一个字符出现的数量。然后将数量和对应字符使用一个Pair暂存到一起,让其可以插入Vector中使用Sort(原创 2021-07-03 11:38:57 · 121 阅读 · 0 评论 -
【LeetCode刷题笔记:1833.雪糕的最大数量】
考完了,也找到了实习。准备去上海巨人网络了~然后就是紧张的实习生活以及准备秋招。所以开始回到LeetCode当常驻选手了。题目:今天这题如果不使用计数排序法的话,其实就是简单题。只需要简单排序一下数组,然后采用贪心的思路来计算得到最终的结果。(为了复习一下算法,排序并未使用sort,自己重写了一次快排,但是会有一个非常极端的测试用例会超时,所以提交的时候还是用的Sort)代码(C++版本)#include<iostream>#include<vector>#incl原创 2021-07-02 21:16:53 · 83 阅读 · 0 评论 -
【剑指Offer57-Ⅱ.和为s的连续正数序列】
题目:这题其实是衔接上题的。离谱的我又只能想到暴力搜索,但是太慢了。看一眼题解,滑动窗口四个字,我就全明白了。本质上呢是上一题双指针的延续。证明这里就不放了,和前一题的证明大致相同。C++代码:class Solution {public: vector<vector<int>> findContinuousSequence(int target) { int i = 1; // 滑动窗口的左边界 int j = 1; // 滑动窗口的右边原创 2021-05-11 17:03:43 · 49 阅读 · 0 评论 -
【剑指Offer57.和为S的两个数字】
题目:今天这题之所以来写博客是因为解法确实有点巧妙。(我完全没想到来着)我一开始想的是暴力搜索,但是毫无疑问会超时。于是用了一个二分查找法来优化它。但是效率也不是很理想:class Solution {public: vector<int> twoSum(vector<int>& nums, int target) { vector<int> sup; for(int i=0;i<nums.size();i++){原创 2021-05-11 16:36:50 · 66 阅读 · 0 评论 -
【剑指Offer54-二叉搜索树的第k大的节点(附带排序二叉树创建测试)】
题目:很简单。反向中序遍历然后提前退出就可以得到答案了。不过这道题我为了加深我非递归中序遍历的印象,使用了正向中序遍历迭代的方式:C++代码附带测试:#include<iostream>#include<algorithm>#include<vector>#include<stack>using namespace std;/** * Definition for a binary tree node. * struct TreeN原创 2021-05-04 17:19:36 · 68 阅读 · 0 评论 -
【剑指Offer58-Ⅱ.左旋转字符串】
题目:其他方法都还好,也不难理解。但是这个旋转三次的做法是真的牛逼。先翻转前k个字符再翻转后面的所有字符最后整体翻转class Solution {public: string reverseLeftWords(string s, int n) { reverse(s.begin(),s.begin()+n); reverse(s.begin()+n,s.begin()+s.size()); reverse(s.begin(),s.en原创 2021-05-03 21:15:29 · 72 阅读 · 0 评论 -
【剑指Offer53-Ⅱ.0~n-1中缺失的数字】
题目:这题的二分查找法确实不错。不过这建立在数组必须初步有序的情况下。如果数组无序的话,则还需要进行排序。不过由于是0~n-1的排序,所以相对来说也比较简单。直接将每个数字换到对应的位置上就好了。我这里想介绍的反倒是另一种方法,数学差值法。想到这个主要是因为之前还有做过两个数组找出少了哪个数字的题。核心思想是累加数组中的所有元素然后去和一个特定值比较。方法很简单,这里就直接上代码了:class Solution {public: int missingNumber(vector<原创 2021-05-03 20:35:06 · 53 阅读 · 0 评论 -
【剑指Offer53-Ⅰ.在排序数组中查找数字】
题目:今天这题使用二分查找加速即可。不过我都忘了C++还有upper_bound和lower_bound这两个函数了。直接相减就可以得到对应的数量。C++代码:class Solution {public: int search(vector<int>& nums, int target) { return (upper_bound(nums.begin(), nums.end(), target)-lower_bound(nums.begin(),原创 2021-05-03 20:22:46 · 52 阅读 · 0 评论 -
【剑指Offer50-第一个只出现一次的字符】
题目:暴力搜索的复杂度是N^2,所以我们得想个优化办法。我们先遍历字符一次,在map中存入每个字符的频数。然后再遍历一次返回第一个频数为1的字符。C++:class Solution {public: char firstUniqChar(string s) { unordered_map<int, int> frequency; for (char ch: s) { ++frequency[ch]; }原创 2021-05-02 16:41:10 · 73 阅读 · 0 评论 -
【剑指Offer48-最长不含重复字符的子串】
今天这题只要想清除这个点就很好做了:最长的子串一定是通过滑动窗口得到的什么意思呢?就是比如第一个示例里面的abcabcbb。窗口一开始为空,不断插入直到有abc。那么下一个a进来的时候,我们应当弹出第一个a来保持窗口内的字符唯一。如果这个a在子串的中间,则需要不断弹出直到末尾的元素能进来。这样遍历一遍整个字符串,中间得到的最大值就是答案。并且不会有任何漏掉的情况。我这里使用的是两个时间复杂度可能相对较高的容器set和queue,但是比题解可以用在更宽泛的。set用于记录当前窗口中是否已经含有元.原创 2021-05-02 16:11:03 · 44 阅读 · 0 评论 -
【剑指Offer47.礼物的最大价值(DFS与动态规划)】
题目:今天这题算是十分常规了。DFS可以做但是最后一个用例会超时。动态规划就是常规的做法,动态转移方程为:dp【i】【j】 = max(dp【i】【j-1】,dp【i-1】【j】)+grid【i】【j】初始化第一行和第一列就可以了。没有什么难度。两种方法的代码:(附带测试)#include<iostream>#include<algorithm>#include<vector>#include<unordered_map>using n原创 2021-05-02 15:29:52 · 116 阅读 · 0 评论 -
【LeetCode刷题笔记-1101.在D天内送达包裹的能力】
题目:今天这题有点意思。我一开始想的是暴力搜索法,针对每一个数组里面出现的元素,从小到大分别列举,直到最接近D天的那个运载能力。但是这样做会存在一些问题,会发现运载能力的最小值必须是weights数组里面的最大元素。因此列举应当是从这个最大元素不断累加其它元素,这样就会变的很复杂。于是我看了题解。题解的思想本质上和我的做法是一样的,只不过是使用二分查找极大的加速了这个过程。思路:1.从上述说明中,可以得到运载能力的最小值一定是weights数组中的最大值。而运载能力的极大值则是所有的元素一天送原创 2021-04-26 13:42:27 · 90 阅读 · 0 评论 -
【LeetCode刷题笔记(不计数了)-363.矩形区域不超过K的最大数值和】
题目:这题的测试数据很弱,暴力搜索也是可以偶尔通过的。但是这里追求一个更快的优化办法。(虽然本质上我个人觉得就是暴力的优化方法)首先,由于这个矩形的四个顶点都是不固定的,而且如果采用类似DFS这样的算法,会有一个舍弃和矩形形状的问题,想想就十分复杂。所以我们必须放弃这种搜索方式。其次,对于矩阵区域的做法,我们常常可以见到将行或者列进行固定,然后动态搜索一边的做法。这里的优化方式采用的是累计列和,然后搜索行的方式。这里引用一下评论区大佬的图片:累计列的和然后搜索行这种累计方法最巧妙的地方在于原创 2021-04-22 11:21:35 · 85 阅读 · 0 评论 -
【剑指Offer46-把数字翻译成字符串(DFS和动态规划)】
题目:这题我一开始想到的就是DFS遍历。因为之前有做过这种拆分问题。然后一看今天的每日一题(91.解码方法),好家伙,一摸一样。只不过那边的拆分需要进一步考虑‘0’的影响,但是本质上是一样的。我们先来说说DFS的做法:很简单,就是一直往下递归遍历就好了。只需要考虑每次是拆一个字符,还是拆两个字符,解空间类似一个二叉树。因为画图之后会发现有很多重复计算,所以用一个map数组去存储遍历到当前索引值的解个数。如果存在的话,说明已经计算过了,直接返回即可。至于动态规划的做法,我觉得和DFS是一个反向的过程原创 2021-04-21 15:59:01 · 86 阅读 · 0 评论 -
【剑指Offer44-数字序列中某一位的数字】
题目:两种方法,当位数不大的时候就不用数学分析了,直接暴力破解也行,不过有时会超时。class Solution {public: int findNthDigit(int n) { string ans = ""; int count = 0; for(int i=0;i<=n;i++){ while(ans.length()<=n){ ans += to_string(count); count++; } } return (i原创 2021-04-21 14:41:21 · 52 阅读 · 0 评论 -
【剑指Offer45-把数组排成最小的数】
题目:注:此题与主站179题本质上是一样的首先,这题如果要严格证明的话,是要采用数学方法证明的。但是也有比较好理解的非严谨证明的方式(毕竟面试让你求证是有难度的)。现在我们只任意考虑数组中的两个数字,比如示例二中的30 34.毫无疑问,要得到最小值30要排列在34的前面,因为3430>3034。那么我们是不是就可以得到一个推论,如果X和Y要组合成为最小数字,是不是就去比较是X在前的数字大还是Y在前的数字大?那么对数组中的任意两个数字都作此比较得到的序列是不是就是最小序列?(因为每一对都严原创 2021-04-21 14:04:42 · 93 阅读 · 0 评论 -
【剑指Offer38-字符串的排列(附带板子)】
题目:今天这题和上次打印1-n位数的所有数字的题目很像。因为都是用到了全排列这个算法。不一样的是,上一次基本是限定了只能在1-9里面选,而且每一位其实是可以不一样的。这一次是长度限定,字符限定,并且重复字符需要跳过去考虑。于是,我们就使用了与上次“拼接”不同的“交换”策略,去交换字符串里面的每一位。这样,就保证能实现前两个条件,只用多考虑重复字符的处理。不过本质上都是DFS算法。C++代码:#include<iostream>#include<vector>#inc原创 2021-04-19 15:37:40 · 60 阅读 · 0 评论 -
【剑指Offer39-数组中出现次数超过一半的数字】
题目:这题的哈希表判定和排序找数组中点元素的方法都很好想。就是这个投票模拟法太秀了:我们假设每个人写的数字都是一张选票。那么这个要找的就是胜出的人。那么怎么算最快呢?直接判断相邻数字是否相同就好了比如3 1 1,一开始假设众数是3,vote(票数)设定为1,但是遇到了1,票数-1.此时已经没有票了。因此需要将众数设定为下一个1,vote设定为1,最后返回这个众数就行了。再比如,3,3,3,1,1,2,4,3,3一开始假设众数是3,vote设定为1,连续两票3,因此vote = 3。1,1,2抵原创 2021-04-18 10:56:32 · 47 阅读 · 0 评论 -
【剑指Offer34-二叉树中和为某一值的路径】
题目:二叉树板子题目,主要考察的是二叉树路径存储和递归。这种题不建议使用非递归遍历法写(我说的就是自己),因为会需要更多的辅助空间,同时左右子树切换和回溯条件是很难进行判断的。如果用递归就会好很多。C++代码附带测试:#include<iostream>#include<vector>#include<algorithm>#include<stack>using namespace std;/** * Definition for a原创 2021-04-18 10:36:57 · 53 阅读 · 0 评论 -
【LeetCode刷题笔记92-26.删除有序数组中的重复项】
题目:今天这题发出来其实是为了提醒自己可以使用algorithm里面的函数,一些笔试里面就没有必要自己再去写这种函数了。今天这题按照他的要求做就可以了,直接使用双指针。不过使用函数distance和unique的话,一行就能写完#include<iostream>#include<vector>#include<algorithm>using namespace std;class Solution {public: int removeD原创 2021-04-18 09:18:06 · 117 阅读 · 0 评论 -
【剑指Offer33-二叉树搜索树的后序遍历】
题目:这题的单调栈做法十分不好想,因为要有十足的观察力才行。这里我使用的是一般通解,即递归法:对每一个区间都去找到左右子树的分割节点,然后判断是否所有右子树(因为左子树元素在划分时能保证都小于当前遍历时的根节点)元素都满足这个条件。如果满足,就继续递归。C++(附带测试,二叉搜索树请使用数组创建)#include<iostream>#include<vector>#include<set>using namespace std;struct Tre原创 2021-04-17 14:26:32 · 59 阅读 · 0 评论 -
【剑指Offer32-Ⅲ从上到下打印二叉树Ⅲ,标志+辅助栈】
题目:这题和前两题本质上是一样的。只不过增加了奇偶判断而已。这里我们使用一个mark标志来记录是该向左还是向右。向左存储的话则先用一个辅助栈记录,最后依次弹出进入辅助数组即可。C++代码#include<iostream>#include<vector>#include<queue>#include<stack>using namespace std;/** * Definition for a binary tree node.原创 2021-04-16 16:28:24 · 42 阅读 · 0 评论 -
【剑指Offer32-Ⅱ从上到下打印二叉树Ⅱ】
题目:这题本质上和上题从上到下打印二叉树Ⅰ是一样的,只不过涉及到如何分层。这里我参考的是评论区K神的方法(我太笨了,第一时间没想到),每一次都动态获取当前队列的长度分层即可。C++代码:#include<iostream>#include<vector>#include<queue>using namespace std;/** * Definition for a binary tree node. * struct TreeNode { *原创 2021-04-16 16:04:54 · 42 阅读 · 0 评论 -
【剑指Offer32-Ⅰ.从上到下打印二叉树(附带测试)】
题目:题目的意思就是写一个层序遍历。那么我们直接常规的使用队列就好了。遍历到每一个节点,出队,并且进入答案输出数组,然后将它的左右子节点按顺序入队。直到队列中没有元素为止。C++代码附带测试:#include<iostream>#include<vector>#include<queue>using namespace std;/** * Definition for a binary tree node. * struct TreeNode {原创 2021-04-16 15:41:13 · 47 阅读 · 0 评论 -
【剑指Offer31-栈的压入、弹出序列】
题目:这题很轻易就能想到使用辅助栈。只不过我自己写的代码太麻烦了,原因是有一个地方没有转过弯来。我原本设想的是,不断找到需要弹栈的元素,然后进行一一匹配。如果出现了无法匹配的情况,就返回False。匹配完成的话,并且两个数组的指针都指向了数组尾部,那么说明匹配成功。但是这样太绕了,因为我忽略了一个很显然的事实:pushed数组如果能和popped匹配,则所有元素都需要进入辅助栈一次(包含了刚入栈就弹出的情况)那么这题就显得十分清晰了。当每一个元素入栈时,判定是否和poped数组待匹配的元素相等。如原创 2021-04-16 15:04:47 · 71 阅读 · 0 评论 -
【LeetCode刷题笔记90-213.打家劫舍Ⅱ】
题目:其实这题很容易能想到使用动态规划做(刚开始我还想了滑动窗口来着)。因为对于任何一间房子,都只有偷和不偷两种情况,偷的话则只能从dp【i-2】+nums【i】得来,否则,只能从dp【i-1】得来。动态转移方程:dp【i】 = max(dp【i-2】+nums【i】+dp【i-1】)然后,这题首尾是相连的。我觉得思考角度可以和题解有一些差别。题解是选择偷A或者偷B,代表这两个里面必须偷一个。我觉得不如这么思考,偷第一家或者不偷第一家。偷第一家的话,整体范围就会-1,不偷第一家的话,起始点+1,整原创 2021-04-15 12:05:34 · 86 阅读 · 0 评论 -
【剑指Offer41-数据流中的中位数】
题目:今天这题的题解妙啊,和TOPK问题有异曲同工之妙。因为想要得到O(1)的计算方式,那么就需要将这个计算过程的时间复杂度分摊到每一次的插入中。再加上要求计算的是中位数,所以可以想到需要最中间的两个数字,就可以想到是不是可以把数组分成两半计算。插入操作又不算特别复杂,并且每次都能得到中间的两个数字,那就把他拆成两个堆。于是,就有了今天的做法。使用一个大根堆和一个小根堆,每一边都保存一半的数字。大根堆里的最小值要比小根堆的里面的最大值大才行。同时还要考虑到奇偶规则。奇数的时候需要具体规定那边的数字多原创 2021-04-14 19:08:07 · 73 阅读 · 0 评论 -
【剑指Offer36-二叉搜索树与双向循环链表(C++附带完整测试)】
题目:嗯。。这题呢我大概想了两种方法。第一种是递归时直接更改,第二种是先遍历得到序列,然后再统一修改。两种方法的时间复杂度上面差不了很多。首先,对于一棵二叉搜索树(排序树),中序遍历可以得到排序序列。因此,我们就很容易可以想到第一种方法。中序遍历一遍,然后使用一个数组存储指向每个节点的指针。然后从头到尾修改left和right指针就可以了。第二种方法就是在中序遍历递归的时候修改,使用一个指针pre来记录上一个节点,来完成整个链表的融合。最后只需要略微调整首尾节点就可以了。具体细节看代码吧包括了原创 2021-04-13 20:41:53 · 111 阅读 · 0 评论 -
【剑指Offer42-连续子数组的最大和】
题目:这题我一开始的思考方向错了。虽然考虑的也是动态规划,但我想的递推是根据要不要舍弃当前元素来计算。后来发现题解的dp【i】是以当前字符数字的数组来划分的,这样即满足了题目条件,同时也方便计算。使用dp【i】来表示,以nums【i】为结尾的子数组的最大值。因为如果dp【i-1】<0,则说明前面的数组对最大和起到反作用,因此直接保留当前元素。如果dp【i-1】>0,则说明前面的数组对最大和起到正向作用,因此对当前元素结尾的数组,直接加上即可。C++代码附带测试:#include&原创 2021-04-13 19:24:40 · 57 阅读 · 0 评论 -
【剑指Offer30.包含min函数的栈】
题目:想要让查找最小值为O(1),那么每次查询的时候必定是一种映射关系。说到映射关系很容易想到哈希表,实际上哈希表这题应该也是可以做的。但是其实更进一步,更好的结构是再用一个栈。因为当一个元素X入栈的时候,可以查看当前元素是否小于辅助栈的栈顶,如果小于,则辅助栈入栈X。如果大于等于栈顶,则栈顶元素再入栈一次。class MinStack {public: /** initialize your data structure here. */ stack<int> m原创 2021-04-13 18:33:00 · 51 阅读 · 0 评论 -
【LeetCode刷题笔记-89 783:二叉搜索树节点最小距离】
今天这题发出来是因为建立测试的时候,是不能使用层序遍历插入的。只能使用二叉排序树的插入方式。除此之外,二叉排序树的中序遍历就是排序好的数组,因此这题就很简单了C++代码(附带测试)#include<iostream>#include<vector>#include<algorithm>using namespace std;/** * Definition for a binary tree node. * struct TreeNode { * .原创 2021-04-13 16:51:10 · 87 阅读 · 0 评论 -
【剑指Offer35-复杂链表的复制】
题目:今天这题的两个解法都很妙。(我是废物,用了一种很复杂的方法)第一种是建立使用unordered_map建立哈希映射。第一次遍历先将所有的节点建立好,然后第二次遍历再去找寻引用。class Solution {public: Node* copyRandomList(Node* head) { if(head == nullptr) return nullptr; Node* cur = head; unordered_map<No原创 2021-04-12 19:11:30 · 43 阅读 · 0 评论