![](https://img-blog.csdnimg.cn/8abe7df25ff547e7b9ae9e0f1f5d6cde.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
LeetCode算法
文章平均质量分 95
LeetCode算法
正在奋斗的程序猿
少年,就要止步于此了吗?
展开
-
怒刷LeetCode的第28天(Java版)
怒刷LeetCode的第28天(Java版)原创 2023-10-24 18:16:18 · 360 阅读 · 0 评论 -
怒刷LeetCode的第27天(Java版)
算法中使用了一个 StringBuilder 对象来存储当前行的字符串,以及一个 List 类型的数组来存储所有排版后的字符串,因此空间复杂度为 O(nL),其中n为单词数量,L为最大单词长度。扫描一遍单词数组找出每一行的单词需要 O(n) 的时间复杂度,对于每一行,排版时需要根据单词数量和剩余空格数量来决定如何分配单词之间的空格,这一步需要 O(L) 的时间复杂度。这道题可以采用贪心的思路,每次尽可能选取更多的单词,同时尽量均匀分配单词之间的空格数量。假设单词数量为 n,最大长度为 L。原创 2023-10-13 08:54:17 · 131 阅读 · 0 评论 -
怒刷LeetCode的第26天(Java版)
整数状态:在这个状态下,输入了数字 0-9。小数点状态:在这个状态下,已经输入了小数点。小数状态:在这个状态下,已经输入了数字并带有小数点。幂符号状态:在这个状态下,出现了字符 e 或 E。幂符号后的符号位状态:在这个状态下,出现了符号位 + 或 -。幂符号后的整数状态:在这个状态下,输入了数字 0-9。终止状态:如果当前输入的字符不合法或者最后一步能够到达终止状态,则说明输入是一个合法的数字。如果所有位都需要进位,则返回新的结果数组,长度为原数组长度加一,首位为1,其余位为0。方法一:有限状态自动机。原创 2023-10-10 22:56:59 · 462 阅读 · 1 评论 -
怒刷LeetCode的第25天(Java版)
第一题题目来源解决方法方法一:闭合为环LeetCode运行结果:第二题题目来源解决方法方法一:动态规划由于机器人只能向下或者向右移动一步,因此到达每个格子的路径只可能来自其上方格子或左侧格子。设 dp[i][j] 表示从起点到 (i,j) 格子的路径数,则有:边界条件为 dp[0][j] 和 dp[i][0] 均为 1,因为对于第一行和第一列上的格子,机器人只能一直向右或向下走到终点。最终答案即为 dp[m-1][n-1],也就是到达终点的路径总数。因此总时间复杂度为 O(mn)。原创 2023-10-07 16:12:38 · 366 阅读 · 0 评论 -
怒刷LeetCode的第24天(Java版)
第二题第一题题目来源解决方法方法一:反向遍历具体的思路是:先去除字符串两端的空格,确保字符串没有多余的空格。从字符串的最后开始向前遍历,找到第一个非空格字符的位置。继续向前遍历,直到遇到空格字符或者到达字符串的开头,记录下遍历过程中的字符数。返回记录的字符数,即为最后一个单词的长度。综上所述,该算法的时间复杂度为 O(n),空间复杂度为 O(1)。LeetCode运行结果:方法二:字符串操作函数除了上述的方法外,还可以使用Java内置的字符串操作函数来解决这个问题。原创 2023-10-06 21:08:20 · 243 阅读 · 0 评论 -
怒刷LeetCode的第23天(Java版)
如果当前区间的起始位置大于当前合并区间的结束位置,说明当前区间与前面的区间没有重叠,我们可以将当前合并区间 [start, end] 加入结果数组中,并更新 start 和 end 为当前区间的起始位置和结束位置。在遍历过程中,每当 count 的值从0变为1时,说明一个新的合并区间开始了,我们将当前点的位置赋值给 start。否则,如果当前区间的起始位置小于等于当前合并区间的结束位置,说明当前区间与前面的区间有重叠,我们可以更新当前合并区间的结束位置为当前区间的结束位置。这样就实现了区间的合并。原创 2023-10-04 10:49:22 · 286 阅读 · 0 评论 -
怒刷LeetCode的第22天(Java版)
第一题题目来源解决方法方法一:回溯算法要解决N皇后问题,可以使用回溯算法。回溯算法是一种通过试错的方式搜索所有可能解的算法。在每一步选择中,我们尝试放置一个皇后,并递归地处理剩下的部分。如果当前方案不能得到有效解,则撤销上一步的选择,回溯到上一层继续尝试其他选择。在判断当前位置是否满足条件时,需要检查当前列、主对角线和副对角线上是否已经有其他皇后。如果存在冲突,则当前位置不可放置皇后。最终,统计计数器count的值即为N皇后问题的不同解决方案数量。原创 2023-10-02 10:20:13 · 219 阅读 · 0 评论 -
怒刷LeetCode的第21天(Java版)
第一题题目来源解决方法方法一:哈希表思路: 首先,我们可以使用哈希表来存储字母异位词分组的结果。遍历字符串数组中的每个字符串,对每个字符串进行排序,得到其排序后的字符串作为哈希表的键。然后将原始字符串添加到对应键的列表中,最后返回哈希表的值即可。综上所述,该解法的时间复杂度为 O(nklogk),空间复杂度为 O(n)。LeetCode运行结果:方法二:计数器数组除了使用哈希表的方法,我们还可以通过使用计数器数组来实现字母异位词的分组。原创 2023-10-01 09:11:10 · 236 阅读 · 0 评论 -
怒刷LeetCode的第20天(Java版)
需要注意的是,由于全排列的数量是非常大的,因此在处理较大规模的输入时,可能会受到时间和空间复杂度的限制。这种方法通过循环遍历矩阵中的四个角落的元素,逐步交换它们的值,实现矩阵的旋转。5、在回溯函数中,首先判断当前排列的长度是否等于 nums 数组的长度,如果是,则说明已经完成了一种排列,将其加入结果集 result 中。在回溯函数 backtrack 中,首先判断如果 path 的长度等于 nums 的长度,则将 path 加入到 result 中,并返回。需要注意的是,全排列的个数可以很大(n!原创 2023-09-30 10:45:51 · 156 阅读 · 0 评论 -
怒刷LeetCode的第19天(Java版)
如果当前位置为1,则直接跳到下一个位置。然后,我们从左向右遍历数组 nums,对于每个位置 i,将当前位置能够跳跃的最大长度 nums[i] 内的所有位置的 dp 值更新为 dp[i] + 1,表示通过当前位置 i 进行一次跳跃。内层循环遍历从当前位置到目标位置之间的所有位置,找到第一个能够跳跃到目标位置的位置,更新 position 和 jumps,然后继续向前遍历。逆向贪婪算法的基本思路是从目标位置开始向起始位置遍历,每次选择能够到达当前位置的最远跳跃位置作为新的目标位置,直到遍历到起始位置为止。原创 2023-09-29 10:49:49 · 557 阅读 · 0 评论 -
怒刷LeetCode的第18天(Java版)
对于数组中的每个位置,如果栈为空或者当前位置的高度小于等于栈顶位置的高度,则将当前位置的下标入栈;需要注意的是,最终的字符串结果需要消除前导零,但是在最坏的情况下,结果字符串的长度可能达到 m + n。需要注意的是,这种方法利用了BigInteger类的内置函数,因此不符合题目要求"不能使用任何内置的 BigInteger 库或直接将输入转换为整数",但是效率上会更高。与置换的方法相比,使用哈希集合的方法在时间复杂度和空间复杂度上都是一样的,但它使用了额外的哈希集合来存储正整数。原创 2023-09-28 20:48:30 · 214 阅读 · 0 评论 -
怒刷LeetCode的第17天(Java版)
第一题题目来源解决方法方法一:过滤和排序这道题的思路和算法如下:首先,将二维数组 restaurants 转换为餐馆对象列表。每个餐馆对象包含 id、rating、veganFriendly、price 和 distance 五个属性。返回排序后的餐馆id列表。因此,总的时间复杂度为 O(nlogn)。空间复杂度方面,需要额外使用一个餐馆对象列表来存储转换后的餐馆信息,所以空间复杂度为 O(n),其中 n 是餐馆的数量。综上所述,该算法的时间复杂度为 O(nlogn),空间复杂度为 O(n)原创 2023-09-27 18:58:22 · 141 阅读 · 0 评论 -
怒刷LeetCode的第16天(Java版)
否则,先递归调用countAndSay(n - 1)来得到前一项的描述字符串,然后遍历该字符串,统计相邻相同字符的个数,并将个数和字符添加到结果中。使用动态规划方法,我们将外观数列的每一项的描述字符串存储起来,避免了重复计算,提高了效率。这种迭代方法的时间复杂度和空间复杂度与递归方法相同,都是O(n^2)和O(n),因为我们仍然需要遍历前一项的描述字符串来计算当前项的描述字符串。总结起来,该算法的时间复杂度和空间复杂度都是O(1),表示算法的运行时间和占用的额外空间都与输入规模无关,非常高效。原创 2023-09-26 22:03:30 · 566 阅读 · 0 评论 -
怒刷LeetCode的第15天(Java版)
第一题题目来源解决方法方法一:哈希表+双向链表LFU(Least Frequently Used)缓存算法的主要思想是根据键的使用频率来进行缓存项的管理。首先,我们需要设计一个数据结构来存储缓存的键值对,并记录每个键的使用计数(即使用频率)。为了支持 O(1) 的时间复杂度,我们可以使用哈希表来存储键值对,并且使用双向链表来维护具有相同使用计数的键的顺序。values因此,get 和 put 操作的时间复杂度都是 O(1)。因此,LFU 缓存算法的空间复杂度为 O(capacity)。原创 2023-09-25 20:36:56 · 579 阅读 · 0 评论 -
怒刷LeetCode的第14天(Java版)
因此,最多需要遍历整个数组一次,时间复杂度为 O(n)。因为二分查找的时间复杂度为 log n,而线性扫描的时间复杂度为 n,所以在数组较大且已排序的情况下,二分查找的性能更好。综合考虑,递归搜索旋转排序数组的算法在最坏情况下的时间复杂度为 O(n),空间复杂度为 O(log n)。需要注意的是,双指针法适用于有序数组或部分有序数组,如果数组无序,则双指针法无法正确找到目标值的开始位置和结束位置。综上所述,线性扫描算法适用于简单的问题或者规模较小的数据集,但在更大规模的数据集上,二分查找算法通常更具优势。原创 2023-09-23 21:42:21 · 202 阅读 · 0 评论 -
怒刷LeetCode的第13天(Java版)
第三题第一题题目来源解决方法方法一:滑动窗口MLeetCode运行结果:方法二:哈希表和双指针除了使用滑动窗口的方法外,还可以使用基于哈希表和双指针的解决方案。这个解决方案使用了双指针的方法。综上所述,该基于哈希表和双指针的解决方案的时间复杂度为O(N * L * M),空间复杂度为O(M)。与滑动窗口的方法相比,其时间复杂度稍高,但实际运行效果可能会因具体情况而有所不同。LeetCode运行结果:方法三:动态规划。原创 2023-09-23 10:27:54 · 142 阅读 · 0 评论 -
怒刷LeetCode的第12天(Java版)
第一题题目来源解决方法方法一:贪心这段代码是使用贪心思路实现的,计算分配钱币给儿童的最多个数。LeetCode运行结果:第二题题目来源解决方法方法一:双指针需要注意的是,虽然上述代码的时间复杂度与 needle 的长度 n 相关,但由于 n 的取值范围很小(1原创 2023-09-22 18:26:51 · 266 阅读 · 1 评论 -
怒刷LeetCode的第11天(Java版)
如果快指针指向的元素与慢指针指向的元素不同,说明找到了一个新的不重复元素,将其存放在慢指针的下一个位置,并将慢指针后移一位。与双指针的方法相比,交换元素的方法具有相同的时间复杂度,但空间复杂度更低,因为不需要额外的数据结构(如 List)来存储元素。这种方法的空间复杂度是常数级别的。这种递归的方法通过逐个处理数组元素,将不等于给定值 val 的元素覆盖到数组的前部分,从而实现移除元素的目的。将 List 转换为数组时,需要创建一个新的数组,大小为 List 的大小,同样占用了额外的 O(n) 空间。原创 2023-09-21 22:32:48 · 350 阅读 · 0 评论 -
怒刷LeetCode的第10天(Java版)
第一题题目来源题目内容解决方法方法一:两次拓扑排序这个解法的思路如下:首先,初始化一个邻接表 g,用于存储树的结构,以及一个数组 degree,用于记录每个节点的度数。遍历边的数组 edges,将每条边的两个节点之间建立连接关系,并更新节点的度数。初始化一个队列 queue,用于存储无金币的叶子节点。遍历所有节点,如果一个节点的度数为1并且该节点没有金币,则将其加入队列。开始循环,直到队列为空。在每次迭代中,取出队列的首个节点 u。将节点 u 的度数减1,剩余节点数 rest 减1。原创 2023-09-21 14:39:51 · 276 阅读 · 0 评论 -
怒刷LeetCode的第9天(Java版)
迭代的思路是,我们创建一个新的链表,用来存储合并后的结果。然后我们使用两个指针分别指向两个链表的头节点,比较两个节点的值,将较小的节点添加到新链表中,并将相应的指针后移一位,直到其中一个链表遍历完毕。递归的思路是,对于两个链表l1和l2,我们比较它们的头结点的值,将较小的头结点作为新链表的头结点,并递归地处理剩余的结点,直到其中一个链表为空。由于题目要求合并两个升序链表,并且新链表也要按照升序排列,因此我们可以使用双指针的方法,依次比较两个链表的结点值大小,将较小的结点接在新链表的最后面。原创 2023-09-20 18:41:54 · 386 阅读 · 0 评论 -
怒刷LeetCode的第8天(Java版)
第二题第一题题目来源题目内容解决方法方法一:双指针和排序根据题目要求,可以使用双指针和排序法来解决这个问题。使用双指针解决四数之和问题的算法思路如下:1、对数组进行排序,将其从小到大排列。2、使用两重循环分别枚举前两个数,其中第一个数的下标范围是0到n-4,第二个数的下标范围是第一个数的下标加1到n-3。4、在两重循环中,使用双指针分别指向当前枚举的两个数之后的位置。6、循环结束后,返回所有符合条件的四个数的组合。总结起来,该算法的时间复杂度为O(n^3),空间复杂度为O(1)。原创 2023-09-19 19:00:14 · 285 阅读 · 0 评论 -
怒刷LeetCode的第7天(Java版)
第二题第一题题目来源题目内容解决方法方法一:二分+贪心根据题目描述,我们可以使用二分查找和贪心思路来解决这个问题。首先,我们定义一个函数check用于判断给定的窃取能力是否满足条件。在该函数中,我们使用贪心策略。我们遍历房屋金额数组nums,对于每个房屋,如果其金额小于等于给定的窃取能力,我们将计数器count加1,并且跳过下一个房屋(因为相邻房屋不能被同时窃取)。最后,如果count大于等于k,说明当前的窃取能力满足条件,返回true;否则,返回false。原创 2023-09-19 10:39:42 · 485 阅读 · 0 评论 -
怒刷LeetCode的第6天(Java版)
时间复杂度为O(mnlogn),其中m是字符串的平均长度,n是字符串数组的长度。时间复杂度为O(mn),其中m是最长公共前缀的长度,n是字符串数组的长度。空间复杂度为O(1)。时间复杂度为O(mn),其中m是最短字符串的长度,n是字符串数组的长度。该算法使用二分查找来逐步缩小最长公共前缀的范围,时间复杂度为O(mnlogm),其中m是最短字符串的长度,n是字符串数组的长度。如果当前索引位置超过了当前字符串的长度,或者当前字符在其他字符串的相同位置上的字符不相等,则表示不匹配,直接返回当前的公共前缀。原创 2023-09-18 19:24:37 · 416 阅读 · 1 评论 -
怒刷LeetCode的第5天(Java版)
如果我们将左指针向右移动一位,那么新的左指针对应的线段高度为 l',右指针不变,那么新容器的底部长度为 r- (l'-l),高度为 min(l', r),因此容器容纳的水量为 (r-(l'-l)) * min(l', r)。计算某个元素时,可以考虑当前两条线段的高度和它们之间的距离,并且选择高度较小的一条作为瓶颈,即容器的高度,并计算容器的底部长度,即线段的距离。然后,从大到小遍历符号数组,每次查看给定的整数中有多少个当前符号所对应的数值,将其加入结果字符串,并用给定的整数减去已经加过的数值。原创 2023-09-18 10:21:52 · 161 阅读 · 0 评论 -
怒刷LeetCode的第4天(Java版)
然后,我们检查 num 是否超出了整数的范围,并根据结果返回相应的值。这个函数首先去除字符串的前导空格,然后判断字符串是否为空或只有正负号的情况,如果是,则返回0。然后,遍历字符串的剩余部分,将连续的数字字符转换为整数,并判断是否超出范围。需要注意的是,在判断是否超出范围时,我们使用了长整型变量 result,而不是直接使用整型变量。这个算法的时间复杂度是 O(m * n),其中 m 是字符串 s 的长度,n 是模式 p 的长度。这个方法的时间复杂度是 O(log n),其中 n 是 x 的位数。原创 2023-09-17 14:00:39 · 187 阅读 · 0 评论 -
怒刷LeetCode的第3天(Java版)
对于第一种情况,dp[i] = max(dp[i-2] + nums[i], dp[i-1]),其中dp[i-2] + nums[i]表示偷窃第i个房屋得到的金额,dp[i-1]表示不偷窃第i个房屋得到的金额。对于第二种情况,dp[i] = max(dp[i-1], dp[i-2] + nums[i]),其中dp[i-1]表示不偷窃第i个房屋得到的金额,dp[i-2] + nums[i]表示偷窃第i个房屋得到的金额。综上所述,该解法的时间复杂度和空间复杂度都是O(n),其中n为字符串s的长度。原创 2023-09-17 10:50:11 · 323 阅读 · 0 评论 -
怒刷LeetCode的第2天(Java版)
反之,如果nums1[k/2-1] > nums2[k/2-1],说明nums2中的前k/2个数一定包含在中位数的前k个数中。在每一次循环中,首先判断右指针指向的字符是否在哈希表中存在,如果不存在,则将该字符加入哈希表,并更新最长无重复子串的长度为maxLen(即maxLen = max(maxLen, right - left + 1))。如果dp[i+1][j-1]为true(即子串s[i+1:j-1]也是回文子串)且s[i]等于s[j],则dp[i][j]为true,否则为false。原创 2023-09-16 15:44:17 · 203 阅读 · 0 评论 -
怒刷LeetCode的第1天(Java版)
如果存在,则说明之前遍历过的某个数字与当前数字的和等于目标值,就返回这两个数字的索引。2、状态转移方程:dp[i] = max(dp[i-2]+nums[i], dp[i-1]),表示选择偷当前房间和前两个房间的收益之和与不偷当前房间的收益中的较大值。同时,通过使用哈希表来存储数字和索引的映射关系,可以在 O(1) 的时间复杂度内快速查找差值是否已存在。该算法的时间复杂度为 O(n^2),因为需要遍历每对不同的数字。空间复杂度分析: 需要一个长度为n的数组来存储中间结果,因此空间复杂度为O(n)。原创 2023-09-16 11:10:18 · 217 阅读 · 0 评论