
手撕算法
以记录思路为主,记录每日的刷题思路
apeiMark
这个作者很懒,什么都没留下…
展开
-
LeetCode-阶乘后的零
【代码】LeetCode-阶乘后的零。原创 2025-03-26 11:18:31 · 267 阅读 · 0 评论 -
LeetCode-插入区间
首先一个比较暴力的方式,就是直接将这个区间加入到末尾,然后根据区间左边界排序后,合并区间即可。第二个解题思路大致是:定义一个minIndex一个maxIndex分别表示待插入区间左边界和右边界位置。原创 2025-03-26 11:17:55 · 211 阅读 · 0 评论 -
LeetCode-最长回文子串
解决这道题的思路要从回文串的定义开始,一个回文串是一个中间对称的字符串,并且看题,题目有提到最长,并且存在着在多个解中寻找最长,那么很大概率是动态规划的题型。如果相等判断串长度是否小于等于3,也就是j - i < 3 【比如4-2 < 3】,如果成立直接为true;第二层循环遍历子串起始位置,并动态计算出子串结束位置j = i + L - 1,如果越界记得break;接着以长度为外层循环,依次判定从长度2开始的子串,并依次递增长度;否则就比较i+1,j-1是否为回文串,即可。最左右两边的两个字符相同;原创 2025-03-26 11:16:43 · 399 阅读 · 0 评论 -
LeetCode-旋转链表
其实旋转链表可以等价于寻找倒数第n个元素,因为旋转其实就是将每一个节点向右移动k%length位置,草稿纸上画一下其实也就是将从倒数第n个元素截断,然后以该元素作为新的头节点,将尾节点接在旧头节点上,另外记得将旧尾节点置为空。原创 2025-03-26 11:16:11 · 137 阅读 · 0 评论 -
LeetCode-逆波兰表达式求值
这道题其实就有点做计算题的感觉,其实就是一个栈存放操作数,然后遇到数字就入操作数栈,遇到字符就将栈中头两个元素取出进行运算,然后将运算结果入栈,重复直到操作数栈为空。原创 2025-03-26 11:15:41 · 292 阅读 · 0 评论 -
LeetCode-从中序与后序遍历序列构造二叉树
这道题与已知前序和中序求其实是一样的,前序的话就是根节点在前,后序就是根节点在后,只需要每次递归从后序中获得根节点,然后再到中序中找到根节点的位置,递归构造左右节点即可。原创 2025-03-26 11:15:10 · 182 阅读 · 0 评论 -
LeetCode-填充每个节点的下一个右侧节点指针 II
层序遍历秒了,首先我们通过层序遍历可以获得每一层的队列,通过先进先出,将每一个出队列的元素指向此时队列首部的元素,如果队列为空就指向null即可。原创 2025-03-26 11:14:39 · 140 阅读 · 0 评论 -
LeetCode-二叉树展开为链表
说白了其实就是将二叉树序列化,并且采用先序序列,也就是只需要通过先序遍历递归方式,将遍历到的节点存入list即可,然后将得到的list遍历,使得每个元素的right指向下一个元素即可。原创 2025-03-26 11:14:07 · 259 阅读 · 0 评论 -
LeetCode-二叉树的右视图
层序遍历秒了,每一层队列最后一个元素存入结果即可。原创 2025-03-26 11:13:34 · 292 阅读 · 0 评论 -
LeetCode-求根节点到叶节点数字之和
这道题其实就是深度优先搜索,因为他需要一次性直接从根节点访问到叶子节点,所以采用深度优先搜索,并且每次搜索时,将原先的值乘以10再加上现有的值即可构成所需数字,然后依次累加遍历到叶子节点的值即可。原创 2025-03-26 11:12:56 · 132 阅读 · 0 评论 -
LeetCode-组合
【代码】LeetCode-组合。原创 2025-03-23 13:32:21 · 204 阅读 · 0 评论 -
LeetCode-电话号码的字母组合
很经典的排列组合,就采用回溯法即可,在回溯法中主函数中通常会申请一个List<>变量用于存放回溯法的结果,在回溯法的递归方法中,一般会传入刚刚申请的结果变量,需要遍历的目标变量,用于存放映射关系的变量,当前位置索引,存放一次结果的变量。有时在回溯过程中有一些情况需要剔除则会需要剪枝。一般形式是刚进入递归方法之后会首先判断是否到达了需要存储的条件,如果没到达则会开始剪枝,然后排除剪枝之后开始回溯。原创 2025-03-23 13:31:44 · 244 阅读 · 0 评论 -
LeetCode-只出现一次的数II
通过逐位统计数组中每个二进制位上 1 的出现次数,利用模 3 判断目标数字的二进制位,最终通过位操作构建出只出现一次的数字。通过HashMap存储每个数字出现的次数,然后找到只出现一次的。原创 2025-03-23 13:30:36 · 185 阅读 · 0 评论 -
LeetCode-只出现一次的数字
由于两个相同的数字进行异或运算得0,0和任何数字进行异或运算得该数字,所以这里符合场景,全部两两异或即可。原创 2025-03-23 13:30:00 · 246 阅读 · 0 评论 -
LeetCode-从前序与中序遍历序列构造二叉树
2.在中序遍历中找到根节点对应的下标;3.根据这个下标划定左右子树的范围;1.先从前序遍历中拿出根节点;4.递归左右子树回到第一步;原创 2025-03-23 13:29:29 · 195 阅读 · 0 评论 -
LeetCode-两数相加
这就是单纯的两个链表进行两数相加,现在是逆序的正好方便我们进行运算,通过同时遍历两个链表,并且设置一个carry值代表是否进位,并在计算sum时加上他,将每次计算好的sum如果大于10则carry为1,并且sum对10取余,然后存入一个新的结果链表中,否则直接存入。另外离开循环后还需要判断当前carry值是否为1,如果有则再加一个节点存入1,否则直接返回即可。原创 2025-03-23 13:28:47 · 176 阅读 · 0 评论 -
LeetCode-括号生成
这道题看题干要求出最多可能的情况,并需要列举,那么就是使用回溯法了,这里还需要解决匹配的问题,通过观察不难看出,要得到匹配的括号,在构建这个字符串的时候 ,每次加入一个括号有两种选择,分别是左括号和右括号,但是有一点就是当你加入的是右括号的时候,左括号要是比右括号还少那么一定不行,所以第一个条件的诞生了【左括号的数目要多余右括号才能加入右括号】,那么第二个条件就是在插入左括号的时候,由于受到括号个数限制,所以第二个条件诞生了【左括号的个数总和不能大于n】。根据这两个条件就可以开始回溯法了。原创 2025-03-23 13:27:04 · 300 阅读 · 0 评论 -
LeetCode-最大子数组和原题
最终,maxAns = 6,即最大子数组和为 6,对应的子数组是 [4,-1,2,1]。1 比 -2 + 1 = -1 更大,从 1 开始新子数组。1 + (-3) = -2 比 -3 更大,继续扩展子数组。4 比 -2 + 4 = 2 更大,从 4 开始新子数组。4 + (-1) = 3 比 -1 更大,继续扩展子数组。6 + (-5) = 1 比 -5 更大,继续扩展子数组。5 + 1 = 6 比 1 更大,继续扩展子数组。1 + 4 = 5 比 4 更大,继续扩展子数组。maxAns 更新后。原创 2025-03-23 13:26:34 · 381 阅读 · 0 评论 -
LeetCode-最小路径和
4.普通情况则代表可以通过上一个或者左边一个走到,那么就是取两种情况最小值即可,f(i,j) = Math.min(f(i-1,j),f(i,j-1)) + grid[i][j];1.当i = 0时,意味着终点在第一行,那么f(0,j) = f(0,j-1) + grid[0][j];2.当j = 0时,意味着终点在第一列,那么f(i,0) = f(i-1,0) + grid[i][0];【因为只能向下走到】3.当i = 0,j = 0,就代表就是在起点,那么f(0,0) = grid[0][0];原创 2025-03-23 13:26:02 · 262 阅读 · 0 评论 -
LeetCode-三角形最小路径和
与矩阵的最小路径和相差不大,不过这次不是只能向下和向右,而是对于第一列来说只能来源于上一行列索引相同的元素,对于最后一个只能来源于上一行列索引-1的元素,而中间的则选择其中最小的即可。原创 2025-03-23 13:25:31 · 115 阅读 · 0 评论 -
LeetCode-Pow(x, n)【快速幂】
快速幂主要是两个思想【位运算&分治】,分治是因为,就比如我要算2^{8},那么我就可以算(2^{4})^{2},那么我在算2^{4}的时候又可以把他替换成(2^{2})^{2},以此类推达到分治的目的。另外如果n为奇数怎么办,那就是把他转化成偶数然后最后的结果多乘一个x即可。【判断n为奇数可以直接用n & 1,也就是看二进制位最后一位是否为1】b每次除以二其实可以通俗的理解为(2^{4})^{2}中的4变成2的过程。如果n为负数怎么办,先把x变成1/x,n变成-n再计算。原创 2025-03-23 13:25:00 · 123 阅读 · 0 评论 -
LeetCode-IPO
我们首先思考,如果不限制次数下我们可以获取的最大利润,我们应该如何处理?我们只需将所有的项目按照资本的大小进行排序,依次购入项目 i,同时手中持有的资本增加 profits[i],直到手中的持有的资本无法启动当前的项目为止。商业转载请联系作者获得授权,非商业转载请注明出处。来源:力扣(LeetCode)原创 2025-03-23 13:24:30 · 345 阅读 · 0 评论 -
LeetCode-合并区间
首先题目没说是有序的,所以我们先通过 Arrays.sort方法将其按照第一个进行排序,然后依次遍历,初始化一个result结果二维数组,每次取中最后一个与遍历到的当前区间进行比较,如果发现取出的区间的后面一位小于当前区间的前面一位,说明直接添加即可,否则需要将取出的区间也就是当前结果二维数组的最后一个进行变动,区间左边不用变动【因为进行了排序】,区间右边取刚刚比较的两者的最大值即可,最后通过result.toArray返回结果。原创 2025-03-22 22:17:28 · 140 阅读 · 0 评论 -
LeetCode-汇总区间
再遍历的时候初始化两个前后指针,其中一个指针指向当前遍历的数字,然后通过while循环判断条件为后一个数字要比当前数字加一,如果是则继续遍历,直到找到不满足条件的跳出循环并用另一个指针记录下当前下标,然后通过StringBuilder类拼接出区间字符串形式加入result List中,直到遍历完整个数组。其中需要注意要是前后指针相等,则说明只有一个元素不用->符号拼接之间加入结果即可。原创 2025-03-22 22:16:55 · 220 阅读 · 0 评论 -
LeetCode-有效的数独
之所以我觉得有意思是,这道题帮我复习了以下位运算,位运算可以帮助我们很好的判断是否出现了重复数字,所以这里本来需要两个二维数组和一个三维数组,但是经过位运算仅需要三个一维数组即可,因为一个数组内的任意元素都可以看作是一个“一维位数组”,然后通过遍历,将遍历到的元素通过左移位并与该相对三个数组的位置的元素进行与运算,就将其标记起来了,然后再通过判断当有重复数组时,进行与运算会导致该数大于0,从而判定他重复。原创 2025-03-22 22:16:09 · 180 阅读 · 0 评论 -
LeetCode-颠倒二进制位
其次,我们也可以使用位运算解决,每次取出原数最后一位并将其通过左移运算放在反转后的位置上,与新数res做或运算保存数据,重复直到原数为0。当然该题还可以采用分治思想,也是前面库的底层实现。首先java中有库可以一键实现。原创 2025-03-22 22:15:38 · 122 阅读 · 0 评论 -
LeetCode-存在重复元素 II
显然这道题是关于判断是否有相等元素的题,判断是否有重复用HashSet准没错,但是他还要求有下标范围限制,那么就用HashMap在存储唯一键的同时保留下标用于判定范围【值得注意的是,当比较完后发现下标范围超过了需要更新Map中的下标范围,防止你一直拿最先发现的那个去比较。首先想到的就是暴力枚举法,通过两个循环遍历所有可能的结果,然后判断是否存在。原创 2025-03-22 22:14:08 · 123 阅读 · 0 评论 -
LeetCode-字母异位词分组
首先我的解决思路是既然他只是要将含有相同组成但是内部字符位置不同的字符串分类在一起,那我是不是可以通过让字符串排序,这样如果他们是字母异位词那么他们经过排序后必然相等,介于这个思路我设计了以下代码。思路一致,但是复杂度降低了。复杂度还是不太理想哈。原创 2025-03-22 22:13:37 · 158 阅读 · 0 评论 -
LeetCode-反转字符串中的单词
既然是反转,设计一个栈,依次往里存即可,注意排除因为split导致的“ ”空字符串的添加。原创 2025-03-22 22:13:06 · 296 阅读 · 0 评论 -
LeetCode-加油站
最小油量其实就是当该站点到不了下一站点时就会使得油量做减法,从而产生最小油量,并且他还是负数,因为只存在一个合法起点,那么为什么最小油量的下一站就是起点呢?但是如果可以再来考虑,认为每一个节点为起点,依次判断是否能够走完,遍历所有可能的条件,最后返回结果,然后就超时了。对于每个加油站 i,计算从该加油站到下一个加油站的油量变化:gas[i] - cost[i],并将其累加到 s 中。通过记录油量最低的点,可以确保从该点出发后,油箱的油量不会低于 0。s:当前油量,表示从某个起点出发后,油箱中的油量变化。原创 2025-03-22 22:12:35 · 876 阅读 · 0 评论 -
LeetCode-除自身以外数组的乘积
这题其实也就是需要知道除了当前元素以外其他所有元素的乘积,这题我的思路其实起源于之前做过的一个接雨水的题目,我通过从左到右遍历数组获取到每个元素左边所有元素的乘积,再从右到左遍历数组获取到每个元素右边所有元素的乘积,最终用当前元素左边的乘积乘以右边的即可。原创 2025-03-22 22:12:05 · 296 阅读 · 0 评论 -
LeetCode-O(1) 时间插入、删除和获取随机元素
如果不用思路这题也是可以解决的,首先我们要知道他需要什么性质,他需要动态存储元素,考虑List,但是他需要O(1)的时间存取元素,那么ArrayList可以满足需求,LinkedList插入操作和删除操作需要耗费O(n)不适用。另外还需要满足集合的唯一性,所以用HashMap最为合适了。不讲武德的我又来了,我直接初始化一个set完成insert和remove的方法,至于随机获取一个元素,直接一个random搞定。原创 2025-03-22 22:11:30 · 396 阅读 · 0 评论 -
LeetCode-无重复字符的最长子串
while (l <= r && check()) {//区间[left,right]不符合题意。//区间[left,right]符合题意,统计相关信息。这里的话只需要额外加一个集合存储出现过的字符即可。//外层循环扩展右边界,内层循环扩展左边界。原创 2025-03-21 19:52:16 · 146 阅读 · 0 评论 -
LeetCode-快乐数
其实根本上来讲这是一个循环问题,如果陷入1的循环返回true,否则返回false,其实我们可以判断为什么不用考虑他会变成无穷大,因为每个数再进入下一步要变成最大的话,比如。还有一种方法,这个题目也很像判断是否为有环链表,那么我们就可以借用快慢指针的方法,如果最后两个指针相遇了那么就跳出循环,并判断是否为1。所以排除第三种情况,那么我们只需要用集合记录每一个出现过的数字,如果再次出现,就跳出循环并判断是否为1。原创 2025-03-21 19:51:39 · 143 阅读 · 0 评论 -
LeetCode-有效的字母异位词
首先想到的就是用哈希表或者数组存储字符出现次数,然后再第二个字符串遍历的时候一个一个减,最后判断map或字符中是否保护值不为0的元素。或者你也可以直接对字符串排序后判断是否相等即可。原创 2025-03-21 19:51:08 · 161 阅读 · 0 评论 -
LeetCode-单词规律
用HashMap即可,同步遍历两个字符串,第二个用 分割为数组在遍历,,并建立一一对应的关系,如果发现其中一个为null了就返回不匹配,说明长度不匹配。如果出现简直不匹配则也返回,最后如果都匹配则返回true。原创 2025-03-21 19:50:35 · 210 阅读 · 0 评论 -
LeetCode-同构字符串
只需要用哈希表或者一个boolean的26长度数组标记s,t分别存在的不同字符数量,相等即可,否则false。原创 2025-03-21 19:50:05 · 99 阅读 · 0 评论 -
LeetCode-长度最小的子数组
原题链接:209. 长度最小的子数组 - 力扣(LeetCode)首先明确是子数组不是子序列,然后需要找到长度最小的子数组,涉及到子串,子数组,和长度都可以采用双指针的办法(其实变相在这里就叫做滑动窗口,根本上也就是了两个指针),用头指针和尾指针标识一个子数组,而这里的判断条件是子数组中(也就是两个指针)中的所有数字的和大于等于target,既然要算一个数组的和,那么我们要一个个遍历并累加,所以我们可以想到何不在构建的时候就累加呢,所以就有了滑动窗口的概念,当我的右指针向右滑动时,就会往数组中加入一个数,这原创 2025-03-21 19:49:35 · 120 阅读 · 0 评论 -
LeetCode-长度最小的子数组
原题链接:209. 长度最小的子数组 - 力扣(LeetCode)首先明确是子数组不是子序列,然后需要找到长度最小的子数组,涉及到子串,子数组,和长度都可以采用双指针的办法(其实变相在这里就叫做滑动窗口,根本上也就是了两个指针),用头指针和尾指针标识一个子数组,而这里的判断条件是子数组中(也就是两个指针)中的所有数字的和大于等于target,既然要算一个数组的和,那么我们要一个个遍历并累加,所以我们可以想到何不在构建的时候就累加呢,所以就有了滑动窗口的概念,当我的右指针向右滑动时,就会往数组中加入一个数,这原创 2025-03-21 19:49:01 · 175 阅读 · 0 评论 -
LeetCode-H 指数
我们可以看出筛出数字的规律时从小到大的,并且都是数组中的元素,所以我们可以想到将数组排个序,【0,1,3,5,6】,你还会发现他们被筛选出去之后其实在他后面的都比他大都可以满足条件,也就可以得出每次遍历满足条件的个数其实就等于用总数字个数减去1,那么这道题就好解决了。对于0,满足条件的有5个,满足大于0 ==》推出第一个判断条件,我如果选择0,那么我需要至少有0个数字满足大于0;对于1,满足条件的有4个,满足大于1 ==》 第一次筛出一个数字,这个数字是0。原创 2025-03-21 19:48:15 · 288 阅读 · 0 评论