- 博客(44)
- 收藏
- 关注
原创 右旋字符串
字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。输入:输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。翻转字符串中的字符,很常用到的 “整体翻转” 和 “局部翻转”思路:先对abcde翻转,再翻转fg,然后整体翻转。输出:输出共一行,为进行了右旋转操作后的字符串。
2025-10-03 08:33:06
236
原创 151.翻转字符串里的单词
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。双指针思路:先全部翻转,再逐个翻转单词;因为要去除空格,所以我们先移除多余空格。解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。给定一个字符串,逐个翻转字符串中的每个单词。输入: " hello world!输入: "a good example"输入: "the sky is blue"输出: "blue is sky the"输出: "example good a"输出: "world!
2025-10-02 16:39:14
176
原创 字符串:替换数字
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。关于第二点,主要涉及到nums中字符的向后移动,其实我们可以从后向前移动指针,然后利用指针来将nums原字符移动到后面。例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。两个难点,一是需要扩充数组,而是需要将数字变为“number”之后指针需要指向“number”之后。样例输出:anumberbnumbercnumber。
2025-10-01 08:50:23
290
原创 541. 反转字符串 II
其实是有的,本质上最后一段的处理的判断,就是 (str.length - 1)- (i + k - 1)是否>0。那最后一段直接做(str.length - 1)的反转就可以了(如果剩余的是小于k的),其他的都是做前k个的反转。其实 可以以 2k 个字符为区间,实际上题目整理一下就是 每次都反转区间内的前k个或者剩余小于k个的字符。正常的话,第一想法是弄个计数器来判断剩余长度,然后再额外k个k个地移动。那大于0了,还是只处理前k个,小于0了,处理剩下的全部。,从字符串开头算起,每计数至。
2025-09-30 08:55:08
227
原创 344.反转字符串
初始化left指向nums【0】,right指向nums.length - 1。编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组。要求不能使用额外空间,而且给到的是一个 字符型 数组 char【】本题只是字符串类题目的引子,主要是意识到双指针在字符串也是很常用的。大概就这样,模拟下没有发现什么问题,就可以去实现代码了。、使用 O(1) 的额外空间解决这一问题。不要给另外的数组分配额外的空间,你必须。那么双指针是可以去尝试的。
2025-09-29 08:14:53
221
原创 第18题. 四数之和
那么nums【a】+ nums【b】> target时我们只要确保之后的nums【c】+ nums【d】和(nums【a】+ nums【b】)相加不会导致大小减少就好,即 nums【b】>0时 nums【c】、nums【d】也必然>0;或者target>0时,就必然说明nums【b】>0了。这里剪枝 剪的是 外循环确定下来的nums【a】+ nums【b】,而且本题 相加之和不是0 而是target,自然也不能是nums【a】+ nums【b】> 0了;请你找出并返回满足下述全部条件且。
2025-09-28 10:21:09
518
原创 第15题. 三数之和
接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下标就应该向左移动,这样才能让三数之和小一些。如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。不同的三元组是 [-1,0,1] 和 [-1,-1,2]。唯一可能的三元组和不为 0。
2025-09-27 11:01:08
447
原创 383. 赎金信
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。暴力的话两层for循环,同时判断相同后还要删除字符串ransomNote的字符,还是很费时的。magazine 中的每个字符只能在 ransomNote 中使用一次。将ransomNote的字符出现次数存储进一个int【26】的数组里面。最后如果int【26】数组有大于0的,就说明 false。如果可以,返回 true;否则返回 false。再使用magazine相减。
2025-09-27 10:04:44
164
原创 第454题.四数相加II
在使用容器上需要注意,因为题目中的元组 指的是 各个数组的下标值,那么我们两个数组为一组的和 就需要区分下标值(即 如果是不同下标数 之和 是同一个值,那么都要记录不同下标),来记录两数之和的出现次数,那么这里需要记录的就有两个值:两数之和,以及 出现次数。为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500。这里四数之和为0 也可以简化到 类似二数之和,两个数组为一组,有两组,计算一组的两数之和有多少,接着就和两数之后差不多。
2025-09-27 09:35:06
356
原创 1. 两数之和
根据给出示例,很明显的不做去重 和 排序,而且 因为一旦找到这个(target - nums【x】)数值的数字 你还要返回他的下标,所以有映射关系 用HashMap,键值key存储数值(key不可重复),value存储下标(value可重复).给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。时间复杂度O(n * 1),这里提一嘴HashMap的查询效率和增删效率都是O(1),因为是通过哈希运算来定位的。
2025-09-23 08:55:36
283
原创 第202题. 快乐数
快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。但不能和为1,必然是陷入无限循环,判断无限循环,假使这个n很独特,循环出来的每一个数都不一样,但无限循环下 最后必然会出现重复的数字,这就好像一个环,最后是不能和为1的。如果很快就可以是和为1,那么循环是能够比较快结束的,比如19。因此思路就是存储每一个循环出来的数,判断有没有重复出现。
2025-09-22 09:00:44
155
原创 349. 两个数组的交集
哈希表思路:要求结果中的每一个元素都一定是唯一的,那么就要做去重,而且对输出结果顺序没有要求,那么就可以采用set数据结构来做映射(当然因为这里有数组大小限制,你使用int【1000】【2】的结果数组来做遍历也是ok的)暴力解法:两层for循环还要额外空间做是否添加的标记(额外空间是直接用的大小为1000的数组直接映射,因为给出的nums1 2的数值最大为1000,如果不是数组做1000的映射的话,时间复杂度为n³)说明: 输出结果中的每个元素一定是唯一的。我们可以不考虑输出结果的顺序。
2025-09-20 08:37:08
148
原创 242.有效的字母异位词(简单的数组哈希表)
考虑到全是小写字母,那么可以应用哈希表的映射思想,不过这里不需要使用到容器,直接使用26个单位的数组来记录小写字母出现次数表。优化:题目要求的只是字母异位,那么字符串长度相同,而且由于都是小写字母,那么各个小写字母出现次数应该是一样的;示例 1: 输入: s = "anagram", t = "nagaram" 输出: true。3. 遍历字母表,如果有 次数不是0的,说明两个字符串不是字母异位词。示例 2: 输入: s = "rat", t = "car" 输出: false。
2025-09-19 15:28:43
139
原创 142.环形链表II(双指针超绝运用)
那么此时模型就抽象成了 两个🏃♀️跑步的人,速度一快一慢,那么快的人总是先进入 环形跑道,慢的人后进入环形跑道。假设跑的圈数无限,那么当跑得慢的人进入环形跑道后,快的人总会在之后第一次相遇。其中关于快的人要多快,这其实涉及到了第二点的数学运算 以及 关于复杂度的基数选择,这里的基数说的就是快多少倍,这里选择 2倍最好,就是fast一次两步,slow一次一步。为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。
2025-09-18 11:24:37
272
原创 面试题 02.07. 链表相交
⚠️补充这两个链表的尾巴总是一样的(物理地址一样),就像现有不同的两个链表,tailNode.next再指向了 第三条链表的头节点,我们要找的 就是第三条链表的头节点。暴力解法:两层for循环分别遍历链表,直到遇到物理地址相同的节点(⚠️这里节点的相同是指 指针指向的地址相同),时间复杂度O(n²)正如上图给出的补充,既然我们要求第三条链表的头节点,那么要是前两条链表的长度相同,是不是head1 head2同时遍历就可以了?上图中,要移动的是head2,移动的距离就是我们要求的。
2025-09-17 19:15:48
277
原创 19.删除链表的倒数第N个节点(双指针妙用)
而且如果要删除的是实际头节点,就要额外处理它,所以依旧使用虚拟头节点(这里也是多了一次移动下一个节点的操作,由于上文思路是ptr1最后在tailNode就停下循环,那么这多一次的操作可以 再多遍历一个节点,但是这样有点绕, 其实就可以ptr1遍历到null也可以实现,下面给出的代码就是这样)输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]输入:head = [1,2], n = 1 输出:[1]输入:head = [1], n = 1 输出:[]
2025-09-16 21:25:03
289
原创 24. 两两交换链表中的节点
没有用虚拟头节点的思路:交换本身不难,清楚第一个节点firstNode 和 第二个节点seconNode的连接就行(每组操作是以firstNode为起点)⚠️难点主要是 题目要求返回的是 新链表的head,你要单独处理 原head 和 head.next,比较麻烦。使用虚拟头节点:这样返回head就方便很多了,直接就返回dummyHead.next就可以了。你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
2025-09-15 21:09:44
257
原创 206.反转链表
在本题中很明显就是 第一种情况,因为递归结束条件就是cur找到null的时候,pre就找到了新链表的新head。示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL。先说为什么可用递归:当前层处理逻辑(即转置节点)这部分是 机械的、相似重复性的。题意:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。递归法:递归三要素(传入参数和返回值,递归结束条件,当前层处理逻辑)递归结束条件:cur遍历完链表,指向null。循环结束是cur遍历完链表。
2025-09-13 14:51:14
169
原创 707.设计链表(单链表实现)
像我给出的代码中的for循环,为什么总是 <index,因为我统一的标准是 只要这个指针必须最后移动到 最后一个节点(不是空节点,因为在倒数第二个节点 仍然执行node = node.next,所以<index)感觉对于链表 而且对于没有指针概念的Java,节点的增删改查可能需要注意的就是有时候 需要单独考虑头节点。这里则慢慢容易出现链表操作的另一个难点,增删改查 所使用的遍历链表要遍历到 目标节点的当前还是前一个?建议使用循环不变量,代码里面统一标准,不然容易把自己绕晕。
2025-09-12 17:28:44
317
原创 203.移除链表元素(虚拟头节点使用)
示例 1: 输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]( 使用虚拟头节点的话,返回的是dummyHeda.next,因为head是不移动的)示例 3: 输入:head = [7,7,7,7], val = 7 输出:[]如果不使用虚拟头节点的话,按照原来思路,cur是直接指向head 这样初始化的。示例 2: 输入:head = [], val = 1 输出:[]链表基础,主要是学会在链表中使用虚拟头节点。就这样,本题还是很轻松的。
2025-09-11 20:49:20
304
原创 44. 开发商购买土地(前缀和应用)
其实还不是最简的,因为例子是竖分割线,最好的办法是第一部分直接用 列前缀和 计算一二两列的和就是第一部分了,至于第二部分,可以在输入土地权值二维数组时同时计算 所有土地的权值总和valSum,直接减去第一部分就可以了。需要注意的是 分割线分为 横割线 以及 竖割线,因此前缀和数组也要分 行前缀和rowPreSum 以及 列前缀和colPreSum(暴力解法中的for里面嵌套的n²也是需要这样区分的)然后第二部分的总和计算,第一行的3,第二行的3,第三行的3。接下来的 n 行,每行输出 m 个正整数。
2025-09-10 23:08:18
981
原创 58. 区间和(前缀和基础)
特别是在题中测试数据有可能达到10w的情况,暴力解法一个个遍历相加时间开销是比较大的(如果n是5w,求区间【3, 4w9k】)第一行输入为整数数组 Array 的长度 n,接下来 n 行,每行一个整数,表示数组的元素。随后的输入为需要计算总和的区间,直至文件结束。那么在n行的输入数组元素的同时,其实就可以同时 求和前缀和(添加一个元素,前缀和counts加加上这个数值)给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。做相减时注意给出代码的前缀和数组是左闭右闭相加形式的元素和。
2025-09-09 22:26:30
326
原创 59.螺旋矩阵II
没有在代码全文都遵循一个“循环不变量”的话,就容易在一列全排序,下一行只排序了(行元素数目 - 1)个,下一列也是这样恶性循环。需要注意的就是,每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理。输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]初始思路:没有什么特别的数组上的技巧,主要 讲解“循环不变量” 的概念,考验基本功的一题。主要目的是避免写完代码,一运行报错 接着就是漫长的修修补补。
2025-09-08 23:07:58
228
原创 力扣209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。示例:输入:s = 7, nums = [2,3,1,2,4,3]输出:2解释:子数组 [4,3] 是该条件下的长度最小的子数组。
2025-09-07 12:25:46
717
原创 977.有序数组的平方
对于 -11 -4 0 1 1 3 5 9,可以观察到 以自然数中最小的元素 0为起点,左右延伸 元素的绝对值是递增的,则在数组左右两头的元素 必定是其中一个的平方 成为当前新数组(忽略已经重新排序好的元素)的最大元素,即需要排序到当前新数组(忽略已经重新排序好的元素)的最右边(因为递增)说到这里,就有点 双指针的味道了,因为 “忽略已经重新排序好的元素” 在代码上实现就是 right指针(初始指向nums[nums.length - 1])在排好最大的平方元素后,需要做 左移一位的操作(right--)
2025-09-06 12:11:55
316
原创 27.移除元素
示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。模拟一下,你想想 数组23232,target是3,在第一次slow 和 fast同时移动到下标1 元素3时,要实现的就是要 替换这个3。
2025-09-04 20:41:58
147
原创 da2 4.15
二叉树递归算法:感觉在写递归前,最好在纸上写终止条件,当前层逻辑,传入参数和返回值;感觉在纸上写部分代码 还有 逻辑思路,会提炼自己的熟练度,接着写代码就有思路,遇到问题也:不至于慌里慌张。无向图的矩阵 邻接表(顶点vex数组➕单链表,由于对称性同时处理两个对称顶点) 多重邻接表(llink从左看 从而链接,rlink从右往左看 从而链接)有向图的正逆向矩阵 正逆向邻接表 十字链表。强连通子图(最大的子图,连通)完全图(任意两点存在路径)连通图(任意两点可达)
2025-04-16 08:16:20
221
原创 day1 4.14
感觉递归总是很难想全面,终止条件容易写漏,递归逻辑在返回参数上有点抽象,想问问大家是怎么学习的递归算法的。觉得状态不对,放了好几天假调整,或许之前有点太急了,还是得一件事一件事来做。
2025-04-15 08:12:01
114
原创 day12 4.8
二叉树,树,森林 的各种相互转化:主要是对孩子兄弟节点的转化。哈夫曼树(最优二叉树):左零右一,权重小的排在左边。哈夫曼算法:处理可以使用权重、重复思想的二叉数。
2025-04-09 08:47:39
127
原创 day10 4.2
array<类型, 长度> 数组名称: 和普通数组一样,array数组长度是固定的,但是更加稳定,安全( Kimi回答:在 C++ 中, std::array (来自 C++11 标准的 <array> 头文件)相比普通数组(C 风格数组)在稳定性和安全性上有以下几个显著优势:1. 边界检查(Bound Checking)普通数组:普通数组没有内置的边界检查,访问越界元素会导致未定义行为(Undefined Behavior),这可能导致程序崩溃或数据损坏。// 默认初始化,初始大小为 0。
2025-04-03 10:47:30
936
原创 day7 3.30
这样就能在每一次遍历中,通过获取原三元组表中元素的列数j,然后通过data[ copt[j-1] ]就能直接知道新三元表要开始存储 该j列的第一个元素的位置。特别注意,存储之后,copt[j]需要自增+1,因为如果j列有两个(以上)元素的话,存储了第一个元素后已经占用了新三元表的一个位置,所以需要指向下一个位置。稀疏矩阵的转置算法(行逻辑链接的矩阵):不断遍历存储矩阵的三元组表,每次都取出表中 j 列最小的那一个三元组,互换行标和列标的值,并按次序存储到一个新三元组表中。
2025-03-31 15:04:14
267
原创 day6 3.29
2.2 行逻辑链接的顺序表:其实就是多了一个rpos数组,专门记录每一行的第一个非零元素 在 三元组表中的位置,这样在(按三元组表判断i和j相同时)输出矩阵时,直接从这个非零元素的行列位置开始,直到遇到下一行的首个非零元素,这样就结束了这一行的 0 和 非0元素的输出。2.36 输出十字链表:按需,直接选择一个数组开始(从行开始,或者从列开始),然后直接从数组的每一个数组内容的头指针开始输出,接着再到下一个数组内容的头指针,反复以上操作。1.1对称矩阵:i(i-1)/2+j-1为指定的元素位置。
2025-03-30 15:09:31
672
原创 day5 3.28
要是学理论太急的话,遇到算法难点 带来的精力消耗感觉会更多(其实我是感觉 学理论看书看视频消耗热情,精力会特别快,这时候去做下实操,慢下来思考,学到的东西也会沉淀下来,潜移默化的,同样也比干学有成就感,恢复热情,不至于后劲不足)3求助 还有个问题,在敲的时候,在做到一半或者差不多的时候,总是有些感觉更好的想法冒出来,大家是怎么处理的,再重构吗,还是先做好原来的思路,再跟AI提一嘴新的想法。晚上刷了两个钟的电影解说哈哈,因为周五晚了,其实也还好吧,放松了不少。栈和队列:括号匹配,循环队列,一道队列。
2025-03-29 12:11:41
408
原创 day4 3.27
以行序为例,想知道在 转化到一维数组中第i行j列个元素的位置,可以模型化为 除去第i行的正/倒三角模型➕所找元素所在的那一行:因此总量有 i(i-1)/2 + j -1 (减一是因为数组从 0 开始计数)。吐槽:这两天学的时候总是进入不了状态,有点烦,也急不来,先调整好心态吧,自学是场持久战;还有时间就继续cpp。va_start,va_list,va_arg,va_end:指向 对传递的调用可变参数(...)的指针。bonus 即 每一维度的 每行/列 可容纳的数据数量(基于维度的边界最大可容纳量)
2025-03-28 09:13:36
186
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅