自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 如何理解递归?

现实中,使用递归求解问题,一般不会是这种,清晰直观的数学公式,通常需要自己思考出临界条件,原问题和子问题的关系,以及函数f(n)的定义,和其中的参数以及返回值,函数也可能是vector<int> f(x1, x2,x3,...)这样有不同返回值和多个参数的,需要自己思考清楚函数f的定义。2.递归的本质其实就是“递”和“归”,关键的思维是遇到问题时,懂得分解问题,即一个规模为n的问题,通过“递”的过程,逐步分解为规模为1的问题,而规模为1的问题,通常是直接有解的。,这个问题的答案是直接可知的,1!

2025-04-03 16:58:40 276

原创 前k个频率最高的元素

2.优化思路:小根堆,只保留前k个元素,时间复杂度为O(log(k)),遍历整个哈希表统计的元素O(n),总的为O(nlogk)。暴力解法为O(nlog(n)),优化了不少。1.暴力解法,先用哈希表统计出现的频率,然后存储在pair<int,int>类型的vector容器中,最后对vector从大到小排序,返回前k个元素。给一个整型数组,返回其中出现频率最高的k个元素。

2025-03-30 16:30:28 505

原创 滑动窗口最大值

常用的做法是使用大顶堆(优先级队列)这样的数据结构,但是如果窗口向右移动一位时,最大值恰好是窗口最左边的值,移动后,该值不在窗口内,需要移除。将一个元素放入优先级队列的时间复杂度为O(logn),最坏的情况所有的值都在优先级队列中,复杂度为O(nlogn)。问题在于窗口是移动的,如果暴力求解,每次都遍历窗口求出窗口的最大值,时间复杂度为:每次遍历窗口的长度求出最大值,为k,一共要移动nums.size() - k + 1,O(k(n - k+1)) = O(nk)。一种更好的办法是使用单调队列。

2025-03-29 01:33:21 375

原创 删除字符串邻近的重复项

对于这道题,可以遍历字符串,用栈存储,一旦遇到和栈顶相同的字符,就出栈,最后栈中的字符串就是最后的结果,注意出栈顺序是相反的,需要将栈中最后的结果相反遍历。对于字符串中字符的匹配或者删除等问题,通常会用到栈这个数据结构,要保持这样一个思路。优化的方法是,可以将字符串当成一个逻辑上的栈来使用,而不必额外申请另外的空间。

2025-03-26 22:49:34 345

原创 简单的括号匹配

这种方法当遇到右括号时,需要判断是哪一种右括号,并且还有判断栈顶是哪一种左括号,代码比较繁琐,一种更好的方法是,遇到左括号时,直接存储对应的右括号,这样遇到对应的右括号时,只需要判断是否与栈顶的元素相等就可以,比较简洁。使用栈stack存储遇到的左括号,一旦遇到右括号,就和栈顶的字符比较,看是否匹配,比如。通常是使用栈这种先进后出的数据结构的特性完成。主要是说明一个技巧。注意第一个为右括号时,栈中没有存储元素出现的存储越界情况。]对应栈顶的[,)对应栈顶的(,}对应栈顶的{。

2025-03-26 22:17:27 446

原创 数据结构模拟-用栈实现队列

可以用两个栈来实现,一个栈保存入队的一端,也就是队尾,一个栈保存出队的一端,也就是队首。当遇到出队pop()时,如果stack out不为空,直接出栈,如果为空,那么先将stack in栈中所有的元素移动到stack out中,由于两个栈先进后出的特性,相当于负负得正,正好将stack in栈中想反的先后顺序更正了过来。用栈实现队列的基本操作,包括pop(), push(), empty(), peek().

2025-03-24 23:23:06 407

原创 重复的子字符串

2.根据重复子串组成字串的性质:假设字串为s,那么ss字串去除首字母和尾字母的字串str,如果str中包含s,那么s是由自身某个子串重复组成的。但是除了数学建模这类的问题,要使用数学知识,其他的本质还是穷举出所有的结果,只不过动态规划发现了最优子结构,回溯进行了剪枝,不必列出所有的结果,不重复,不遗漏。例如:abcabcabc,枚举子串长度为2时,每个i, str[i] == str[i - 2],如果不相等,说明不能组成该字串。只要掌握暴力枚举即可,下面的解法可能想不到,可以死记硬背下来,当作结论使用。

2025-03-22 23:54:40 372

原创 KMP-子串匹配算法-关键点理解

在已经匹配的字符串中,如何最长相等前后缀为0,也即是没有相等的前后缀,那么显然,由于已经匹配的字符串在模式串中为模式串的一个前缀,而在主串中为已经遍历过的匹配的字符串的后缀,假设从i开始比较,到j不相等,主串i ~ j-1这一部分是模式串的一个前缀,因为肯定是从模式串的第一个字符开始比较的。xabcxx: 假设此时i遍历到了x,j为i-1结尾的前缀字符串的最长相等前后缀长度,也就是红色部分表示的前缀字符串的最长相等前后缀长度,为2,也即是j指向最长相等前缀的下一个字符c。i-j~i-1是等于0-j-1的。

2025-03-20 23:43:14 1331

原创 反转字符串中的单词-medium

2.通过暴力遍历的结果对比原字符串可以发现,实际上,反转后的结果就是,先将整个字符串反转,然后一个一个单词反转,得到的结果就是最终的结果。小技巧:当数据格式很复杂时,可以先考虑使用O(n)的时间复杂度先对数据进行一遍预处理,可以很方便后续的操作。1.思考过程:首先考虑暴力遍历:从后向前一个一个查找单词进行反转,并使用一个字符串保留结果。中使用至少一个空格将字符串中的。之间用单个空格连接的结果字符串。两者解法的差别在空间复杂度。

2025-03-12 23:57:16 407

原创 数组/字符串填充类问题的双指针解法-不用额外空间,不移动数组元素

第三步:从后向前复制数组。point1向左移动,直到第一个元素;point2也向左移动,同时复制point1指向的元素,这里是每5个元素添加一个空格。第二步:point1指向数组arr的末尾,也就是结果数组的arr.size() - 1的位置,point2指向newSize - 1;显然是暴力遍历:使用一个额外数组/字符串,将一个个字符复制,并且每5个,添加一个空格,再继续复制。第一步:计算得到结果数组/字符串的大小,比如这里newSize = arr.size() / 5 + arr.size();

2025-03-11 22:43:07 271

原创 反转字符串II-题解

1.注意总结训练解题通用的思考过程:暴力遍历?显然这是一道模拟题,只要按照题意模拟操作过程即可。优化考虑:(根据问题性质使用双指针等技巧)。,从字符串开头算起,每计数至。

2025-03-11 22:05:08 249

原创 反转字符串-简单题的坑

反转字符串很简单,直接遍历交换元素就可以或者使用双指针是一样的思路。下面的代码思路是对的,但语法细节上有错误。细节在于s.size()的返回值,是unsigned long类型,当运算出现负数时,会出现意想不到的错误。比如这里的s.size()/2 - 1,当是size大小为1时,s.size()/2结果为0,注意这里的隐式类型转换,0是unsigned long类型,0-1的结果为-1,unsigned long类型的-1的补码被解释为正数,结果是一个很大的正数,导致循环会进行,从而出现range

2025-03-10 23:04:18 346

原创 leetcode-四数之和-详细过程(暴力解法,哈希法,双指针法)

使用四个循环,遍历所有可能的组合,能通过Leetcode测试,但时间复杂度过高O(n^4)。1.基本思路:当遇到一道题时,直接考虑暴力遍历解法,然后再考虑在这个基础上进行优化。二、问题性质,算法技巧,本题是双指针。注意要排序之后才能满足使用双指针的条件。比如数学知识,问题性质(动态规划之类)或其他算法技巧。2.考虑在上面的基础上进行优化。

2025-03-10 18:38:17 298

原创 leetcode 15.三数之和-详细注释(哈希法,双指针法)

观察一下,不难发现,是由于原数组中出现的重复元素,例如这里的-2,导致了重复组合的出现,所以只需要对原数组去除重复元素即可。但是这里面的组合可能有重复的结果,比如排列a, b, c,但是后面又出现了b, a, c,都满足a + b + c = 0。比如{-2, 0, 2}和{0, 2 ,-2},原数组可能为{-2, 0, 2, -2}。然后第二个选a后面的c, 第三个数选c后面的d, e。例如,第一个选a, 第二个要从a后面的数开始选,比如选b,然后第三个数从b后面选,比如c,d,e, ...

2025-03-10 15:50:26 1174

原创 leetcode-四数相加II

使用一个哈希表记录A[i]+B[j]的值以及出现的次数,当双层循环遍历C[k] + D[L]时,如果哈希表中有key = -(C[k] + D[L])那说明有hashmap[key] = x个满足条件的元组。即4层循环,四个数组A,B,C,D得出所有可能的四个元素的组合。只需要找出满足A[i] + B[j] + C[k] + D[L] = 0的元组的个数,所以不需要存储下标信息。通常是对半分,即4 / 2 = 2,分成两组,A[i] + B[j] = -(C[k] + D[L]).

2025-03-06 22:05:44 241

原创 leetcode两数之和-简单题

(其实很多题目的答案都是在暴力遍历的基础上发现问题的性质(例如动态规划之类的),通常的做法是用空间换时间进行优化。1.双层循环遍历除自身以外的所有其他元素,由于题目保证只有唯一答案,所有该元素前面已经遍历过的元素就不需要考虑了。提前结束循环还是快了一点,注意最后面还是要写返回语句,虽然题目规定一定有答案,但语法上条件分支可能会跳过返回语句。例如 数组 = [1, 4, 6, 7, 2, 8, 2, 7] , target = 7。由于题目限制每种输入只会对应一个答案,并且你不能使用两次相同的元素。

2025-03-06 00:05:41 559

原创 leetcode简单题-快乐数

根据题目定义,例如123的下一个数是X = 1^2 + 2^2 + 3^2 = 1 + 4 + 9 = 14,14下一个是1^2 + 4^2 = 17。123->14->17->50->25->29->85->也就是当下一个数是1时,退出循环,返回true,当下一个数与前面出现的数相同时,会进入死循环,此时也要跳出循环,并返回false。这题很容易看出,没有什么数学捷径,也没有遍历,就是单纯的按照题目的定义进行模拟判断。2.难点:1.要求出一个数n,它的各个数位上的数字,例如123,要求出1,2,3。

2025-03-05 22:48:48 446

原创 数组求交集问题-基础

如数组A=[1, 3, 4, 6, 3] 数组B=[1, 3, 7, 4, 4, 5, 7],它们的交集为[1, 3, 4]。1.计算机解决问题的本质除了依据数学原理以及模拟过程以外,就是遍历,动态规划,贪心之类的思想是问题的性质不需要遍历出所有结果,从子问题的解可以推出原问题的解。例如元素1,遍历查找看B中是否有元素1,有,那么1就在交集中,依次对A中每个元素进行上面操作,最终得到交集C。暴力解法就是双层循环,对A中的每个元素,遍历B中是否存在该元素,O(Size(A)*Size(B))。

2025-03-04 23:35:12 563

原创 前缀和在求解区间和问题的应用

就是用一个数组preSum[n],preSum[i]表示从[0,i]的数的和,注意是左闭右闭的区间,那么求解[a,b]区间的和就等于preSum[b]-preSum[a-1],即(X0+...+Xa-1+Xa+...+Xb)-(X0+...+Xa-1)最简单的做法就是直接一个循环,for(i=a;注意点:这里a-1>=0,a>=1,要注意下标越界的问题,即[a,b]a=0时,所以需要加一个条件语句。在一个数组中,要求[a,b]区间内数的总和的问题,叫区间和问题。

2025-01-19 23:44:24 318

原创 遍历螺旋矩阵问题

螺旋矩阵

2025-01-18 12:43:57 370

原创 最小覆盖子串问题

开始时,right向右移动,此时窗口不断扩大,每移动一步,需要检查窗口是否已经满足覆盖子串t,一旦满足,right停止移动,开始移动left,减小窗口的大小,一旦left移动后不满足覆盖子串t的条件,我们就找到了一个当前“最小的覆盖子串”,由于后面可能有更小的覆盖子串,所以right继续移动,重复上面的操作,直到末尾,每次找到当前最小覆盖子串时,比较找到覆盖子串,取更短的作为最小的子串。难点一般在于如何判断窗口是否满足条件,通常要使用哈希表进行辅助。

2025-01-16 20:41:19 511

原创 二、进程管理

1.动态性:指进程有创建到销毁整个生命周期,2.并发性:指进程和其他进程在一段时间内可以同时运行,3.独立性:指进程是独立获得资源和调度的基本单位,与其他进程无关,4.异步性:指进程与其他进程以各自不可预知的速度独立运行。线程物理上由线程ID,程序计数器,寄存器集合,堆栈构成,线程是进程中的一个实体,是被系统独立调度的基本单位,线程不拥有系统资源,只有一点执行指令必不可少的资源,与进程内的其他线程共享进程拥有的资源。引入线程后,进程只是操作系统分配资源的基本单元,而线程作为调度,cpu的分配单元。

2025-01-15 23:59:45 216

原创 滑动窗口解决数组问题的一些理解

3.如何形象理解:其实就是窗口的终止位置end,向数组终点nums.size() - 1扩大窗口,一旦窗口里连续的序列满足了一定条件,就需要缩小窗口,窗口的起始位置要向右移动,去掉窗口里的元素,直到窗口又不满足条件,此时,end又要开始向右移动,直到终点。1.首先明确,滑动窗口解法肯定没有遍历整个子数组,否则,时间复杂度不可能是O(n),也就是说滑动窗口解法在求解的路径上有优化。2.滑动窗口适用于连续的子序列,非连续序列一般不适合。因为窗口只能限制窗口内的元素,限制不了跳跃在窗口外的元素。

2025-01-15 00:41:35 106

原创 数组移除元素常用方法-双指针法

如果实在不好理解,其实看成快指针指向原始数组,慢指针指向一个新的数组,虽然实际上是在同一个数组上进行处理。

2025-01-09 22:23:17 185

原创 一文彻底弄清楚快速排序

快速排序源码

2025-01-08 14:30:32 254

原创 二分查找疑难点-区间问题

二分查找疑难问题

2025-01-07 22:20:45 815

原创 简单易懂的希尔排序的理解

而希尔排序由于是按gap间隔进行直接插入排序的,在gap逐渐变化的某个gap等于某个值时,就会直接把这最大的10个数中的一些放在最终结果的相应的位置上,而且以后只会进行比较操作,并不会再移动这些已经在正确位置上的比较大的数了,这就减少了很多多余的移动操作.希尔排序其实很简单,它和折半插入排序一样,是对直接插入排序的一种优化而已,核心仍然是直接插入排序,只要掌握了直接插入排序的原理,希尔排序手到擒来.gap = 2, 那么得到 {1, 3, 5, 7, 9, 10}, {2, 4, 6, 8, 10},

2025-01-06 16:59:52 816

原创 查找算法-顺序查找

顺序查找与暗恋情书

2025-01-02 14:32:07 202

原创 排序算法-內部排序-1.直接插入排序

通俗易懂的直接插入排序

2025-01-02 10:28:40 328

空空如也

空空如也

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

TA关注的人

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