![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法
文章平均质量分 57
ayu_programer
不积硅步,无以至千里
展开
-
Leetcode-438-找到字符串中所有的字母异位词
字母异位词”,指“字母相同,但排列不同的字符串”。注意这里所说的“排列不同”,是所有字母异位词彼此之间而言的,并不是说要和目标字符串p不同。给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。定义左右指针向右移动,实现滑动窗口的作用。在指针移动的过程中,字符只会被遍历一次,时间复杂度就可以大大降低。字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。另外,我们同样应该考虑,p中可能有重复字母。原创 2024-06-05 23:05:47 · 400 阅读 · 0 评论 -
Leetcode-76-最小覆盖子串
此外,判断当前窗口是否含有所有字母,我们除了可以判断所有字母的次数是否小于等于 0,还可以用一个计数变量 count,把 count 初始化为 t 的长度,然后每次找到一个满足条件的字母,count 就减 1,如果 count 等于了 0,就代表包含了所有字母。由于字符串中只有字母,我们其实可以不用 hashmap,可以直接用一个 int 数组,字母的 ascii 码值作为下标,保存每个字母的次数。记录此时的长度,left 向右移动,开始减少长度,每减少一次,就更新最小长度。原创 2024-05-27 23:02:57 · 130 阅读 · 0 评论 -
Leetcode-239-滑动窗口的最大值
时间复杂度: O(Nk),双重循环,外层遍历数组循环N次,内层遍历窗口循环k次,所以整体就是O(N) * O(k) = O(Nk),表现较差。时间复杂度: O(Nlog(k)),在大小为 k 的堆中插入一个元素只需要消耗 log(k) 时间,因此这样改进后,算法的时间复杂度为O(Nlog(k))。这是一个典型的滑动窗口的问题。空间复杂度: O(N),输出数组使用了 O(N−k+1) 空间,双向队列使用了O(k)。空间复杂度:O(N),输出数组用到了O(N-k+1)的空间,大顶堆用了O(k)。原创 2024-05-21 22:47:16 · 754 阅读 · 0 评论 -
Leetcode-316-去除重复字母
首先,seen 中字符不重复,其大小会受字母表大小的限制,所以是O(1)。虽然看起来是双重循环,但内循环的次数受栈中剩余字符总数的限制,因为栈中的元素不重复,不会超出字母表大小,因此最终复杂度仍为 O(N)。空间复杂度:O(N),每次给字符串切片都会创建一个新的字符串(字符串不可变),切片的数量受常数限制,最终复杂度为 O(N) * C = O(N)。空间复杂度:O(N),每次给字符串切片都会创建一个新的字符串(字符串不可变),切片的数量受常数限制,最终复杂度为 O(N) * C = O(N)。原创 2024-05-06 22:53:40 · 1006 阅读 · 0 评论 -
Leetcode-43-字符串相乘
做计算的时候,外层需要从右往左遍历num2,而对于num2的每一位,都需要和 num1的每一位计算乘积,因此计算乘积的总次数是 mn。而且,某两个数位相乘,num1[i] x num2[j] 的结果(定义为两位数,一位数的话前面补0),其第一位位于 result[i+j],第二位位于 result[i+j+1]。需要计算num1 的每一位和 num2的每一位的乘积。给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。原创 2024-04-28 23:09:56 · 404 阅读 · 0 评论 -
Leetcode-415-字符串相加问题
这里不允许直接将输入字符串转为整数,那自然想到应该把字符串按每个字符char一一拆开,相当于遍历整数上的每一个数位,然后通过“乘10叠加”的方式,就可以整合起来了。时间复杂度:O(max(len1,len2)),其中len1 =num1.length,len2 =num2.length。另外题目要求不能使用BigInteger的内建库,这其实就是让我们自己实现一个大整数相加的功能。给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。1.num1 和num2 的长度都小于 5100。原创 2024-04-28 22:53:17 · 170 阅读 · 0 评论 -
Leetcode-287-寻找重复数
空间复杂度: O(1) (or O(n)),在这里,我们对 nums 进行了排序,因此内存大小是固定的。这里,nums 中的每个数字(n+1个)都是一个物品,nums 中可以出现的每个不同的数字(n个)都是一个 “抽屉”。二分查找最多需要O(logn) 次,而每次判断count的时候需要O(n) 遍历 nums[] 数组求解小于等于 i 的数的个数,因此总时间复杂度为O(nlogn)。时间复杂度:O(n),我们只对数组做了一次遍历,在HashMap和HashSet中查找的复杂度是O(1)。原创 2024-04-27 23:01:02 · 686 阅读 · 0 评论 -
Leetcode-74-搜索二维矩阵
行列坐标为(row, col)的元素,展开之后索引下标为idx = row * n + col;输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,50]], target = 13。输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,50]], target = 3。编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。时间复杂度 : 由于是标准的二分查找,时间复杂度为O(log(m n))。原创 2024-04-27 22:39:01 · 299 阅读 · 0 评论 -
Leetcode-48-旋转图像
这四个矩阵的对应关系,其实是一目了然的,我们完全可以在一次循环内,把所有元素都旋转到位。这个简单的方法已经能达到最优的时间复杂度O(N^2) ,因为既然是旋转,那么每个点都应该遍历到,N^2的复杂度不可避免。旋转图像,这个应用在图片处理的过程中,非常常见。空间复杂度:O(1) 由于我们在一次循环中的操作是“就地”完成的,并且我们只用了长度为 4 的临时列表做辅助。因为旋转的时候,是上下、左右分别对称的,所以我们遍历元素的时候,只要遍历一半行、一半列就可以了(1/4元素)。我们可以利用矩阵的特性。原创 2024-04-15 22:59:12 · 908 阅读 · 0 评论 -
LeetCode-31-下一个排列问题
不过具体操作会发现,如果正序子序列后没数了,那么子序列的“下一个”一定就是整个序列的“下一个”,这样做没问题;但如果后面还有逆序排列的数,这样就不对了。比如 [1,3,8,7,6,2]最后的正序子序列是[1,3,8],但显然不能直接换成[1,8,3]就完事了;而应该考虑把3换成后面比3大、但比8小的数,而且要选最小的那个(6)。接下来,还要让6之后的所有数,做一个升序排列,得到结果:[1,6,2,3,7,8]原创 2024-04-14 23:11:49 · 529 阅读 · 0 评论 -
LeetCode-15-三数之和问题
左右指针,其实借鉴的就是分治的思想,简单来说,就是在数组头尾各放置一个指针,先让头部的指针(左指针)右移,移不动的时候,再让尾部的指针(右指针)左移:最终两个指针相遇,那么搜索就结束了。之前我们搜索数组,时间复杂度至少都为O(N^2),而如果用快排或者归并,排序的复杂度,是 O(NlogN),最多也是O(N^2)。尽管时间复杂度依然为O(n^2),但是过程中避免了复杂的数据结构,空间复杂度仅为常数级O(1),可以说,双指针法是一种很巧妙、很优雅的算法设计。比暴力法的O(n^3),显然有了很大的改善。原创 2024-04-14 22:49:54 · 470 阅读 · 0 评论 -
Hot100-hash表-字母异位词分组问题
这题的关键是找到字母异位词的共同点,即他们的字符出现个数一样多,这样一来可以把每个字符映射到具体的数组上。原创 2024-02-17 19:41:39 · 246 阅读 · 0 评论 -
Hot100-hash表-两数之和
这题相对比较简单,就是用hash表来解决,key为具体数,value为下标,通过containsKey方法来判断是否存在两数之和。原创 2024-02-17 19:33:48 · 179 阅读 · 0 评论 -
JVM篇--垃圾回收器高频面试题
首先CMS垃圾收集器是一种1 老年代的垃圾收集器2 是以牺牲吞吐量为代价来获取最短回收停顿时间的垃圾回收器3 多线程并发的标记-清除算法所以在gc的时候会产生大量的内存碎片,当剩余内存不能满足程序运行要求时,系统将会出现 Concurrent Mode Failure,临时 CMS 会采用 Serial Old 回收器进行垃圾清除,此时的性能将会被降低。CMS 工作机制相比其他的垃圾收集器来说更复杂。初始标记只是标记一下 GC Roots 能直接关联的对象,速度很快,仍然需要暂停所有的工作线程。原创 2024-01-21 22:36:14 · 1466 阅读 · 0 评论 -
贪心算法-点灯问题
X’ 表示墙,不能放灯,点亮不点亮都可;’.’ 表示居民点,可以放灯,需要点亮。如果灯放在i位置,可以让 i-1,i 和 i+1 三个位置被点亮。(4)i 位置是 ‘.’ ,i + 1是 ‘.’,i + 2是 'X’,i 或 i + 1 位置需要放灯,(3)i 位置是 ‘.’ ,i + 1是 ‘.’,i + 2是 ‘.’,i + 1 位置需要放灯,(2)i 位置是 ‘.’ ,i + 1是 'X’,i 位置需要放灯,(1)i 位置是 'X’,不管,来到 i + 1位置。原创 2023-09-25 10:35:30 · 470 阅读 · 0 评论 -
贪心算法-IPO问题
然后,有两个数组,一个cost[],里面记录了每个项目需要花费的资金。一个profit数组,里面记录了每个项目完成后可以获取的利润。然后请你计算出,给你一个初始资金w,和最大项目次数k的情况下,可以获取的最大利润。那么,初始资金只能够花费来进行第一个10的项目,其他项目买不起,然后,第一个项目做完,利润是10,现在手里有20,就可以进行第二个项目了,然后再累加利润,看看能不能再解锁新项目。例如:初始资金10,k=3,cost[10,20,30,40],profit[10,20,30,40]原创 2023-09-21 21:01:59 · 281 阅读 · 0 评论 -
贪心算法-金条切割问题
金条要分成10,20,30。如果先把长度60的金条分成10和50,花费60;再把长度50的金条分成20和30,花费50;一共花费110铜板。一块金条切成两半,是需要花费和长度数值一样的铜板的。比如长度为20的金条,不管切成长度多大的两半,都要花费20个铜板。但是如果先把长度60的金条分成30和30,花费60;再把长度30金条分成10和20,花费30;例如,给定数组{10,20,30},代表一共三个人,整块金条长度为10+20+30=60。之后再把累加值放到小根堆里去,所有的累加和即为最小代价。原创 2023-09-21 20:56:57 · 355 阅读 · 0 评论 -
贪心算法-拼接字符串使得字典顺序最小问题
给定一个由字符串组成的数组strs,必须把所有字符串拼接起来,返回所有可能的拼接结果中,字典序最小的结果。:对数组排序,排序规则是对a+b和b+a的字符串进行比较大小,返回较小的顺序放到数组中最后将数组累加即得。原创 2023-09-21 20:38:35 · 378 阅读 · 0 评论 -
贪心算法-会议室问题
现在给你两个长度一样的数组,starts数组代码每个会议开始的时间,ends数组代表每个会议结束的时间。贪心算法是纯粹的积累经验类型的算法思想,贪心策略的正确性证明是非常困难的,几乎不可能证明正确性,因此,只能通过对数器进行验证。导致它前面的时间浪费了,后面的时间可能正好差一点不够一个会议,这样也很浪费,肯定不是最优解。因此,排除掉1和2,此题的最优贪心算法应该就是3。1.按照最早开始的会议排序,最早开始的优先。2.按照最短时间排序,时间最短的优先。3.按照最早结束排序,最早结束的优先。原创 2023-09-21 20:49:11 · 438 阅读 · 0 评论 -
动态规划问题-求最长回文子序列长度
所以列L 是从N-3出发(N-1和N-2已经填完了);最长回文子序列是 “123c321” 或者1234321 返回长度为7。通过画图知道,每一行依赖于它下边的,左边的格子,左边下角的格子。给定一个字符串str,返回这个字符串的最长回文子序列长度。因为每一个数都依赖它左边的,下边的,左下的 并求最大值。所以 应该从下往上填,但是每一行又是从左往右填写。回文串 开始位置不算, 结束位置不算。开始位置算, 结束位置不算。开始位置不算, 结束位置算。开始位置算, 结束位置算。原创 2023-02-24 09:36:19 · 268 阅读 · 0 评论 -
单链表有环无环相交问题
那么,针对以上结构,我们可以这样处理 1、判断哪个链表更长,把长链表从头节点开始一直指向下一个节点,直至与短链表长度一直 2、长短链表长度相等后,各种开始指向下一个节点,同时判断当前两个指针指向的节点是否相等,期间第一个相等的节点,即为第一个相交的节点。如图所示,若是情况2,那么只需遍历L1的loop1,直至回到loop1,期间若与loop2相遇,那么两个链表的第一个相遇节点就是loop1或loop2。请实现一个函数,如果两个链表相交,请返回相交的第一个节点, 如果不相交,返回null即可。原创 2023-02-21 08:42:45 · 190 阅读 · 0 评论 -
动态规划-最长公共子序列问题
这种由暴力递归转化到动态规划的思路比较容易想到且容易实验操作,针对这种求子序列的问题是一种样本对应模型,都可以基于这种套路求解。原创 2023-02-08 11:30:47 · 476 阅读 · 1 评论 -
归并排序详解-java实现
然后对左边 3 4 2 1 做排序处理,再按照上述求中点方法分为 3 4 和 2 1。:先对对数据以中点进行划分,对左边进行排序处理,在对右边进行排序处理,最后合并。然后对整体进行合并merge(合并时是临时将数据放到一个新数组,谁小拷贝谁)比如针对 3 4 2 1 5 6 0 3。把3,4 排序后为3,4;2,1 排序后为1,2。同理对右边也进行排序处理,合并后为0,3,5,6。所以为 0,1,2,3,3,4,5,6。然后执行merge变为1,2,3,4。原创 2022-12-18 21:33:41 · 115 阅读 · 0 评论 -
快速排序详解-java实现
整体过程:1.先从数组中找一个数作为基准数,2 进行分区,分区时大于这个数得全部放到右边,小于这个数得全部放到左边,等于这个数得全部放到中间(核心过程)3再通过递归再更小得范围执行2步骤,直到递归到只有一个数思路解析比如针对 3 4 2 1 5 6 0 3它的一个思路是首先有一个左边区域和右边区域,左边区域的最靠右的起始下标为-1,右边区域的最靠左的起始下标为length-1然后以数组最后一个数3为界限,大于这个数的都在右边,小于这个数的都在左边首先排的时候index 为原创 2022-12-06 22:02:29 · 860 阅读 · 0 评论