- 博客(20)
- 收藏
- 关注
原创 lec 第15题. 三数之和
接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下标就应该向左移动,这样才能让三数之和小一些。如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。时间复杂度:O(n^2)。
2023-07-12 17:58:53
32
1
原创 lec 383. 赎金信
本题判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成,但是这里需要注意两点。第一点“为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思” 这里说明杂志里面的字母不可重复使用。第二点 “你可以假设两个字符串均只含有小写字母。说明只有小写字母,这一点很重要那么第一个思路其实就是暴力枚举了,两层for循环,不断去寻找这里时间复杂度是比较高的,而且里面还有一个字符串删除也就是erase的操作,也是费时的,当然这段代码也可以过这道题。
2023-07-11 17:34:19
36
原创 lec 1. 两数之和
在遍历数组的时候,只需要向map去查询是否有和目前遍历元素匹配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。本题呢,我就需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是 是否出现在这个集合。那么判断元素是否出现,这个元素就要作为key,所以数组中的元素作为key,有key对应的就是value,value用来存下标。因为本题,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,
2023-07-11 16:49:36
42
原创 lec 第202题. 快乐数
所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。判断sum是否重复出现就可以使用unordered_set。
2023-07-11 11:47:08
37
原创 lec 349. 两个数组的交集
std::unordered_set的底层实现是哈希表, 使用unordered_set 读写效率是最高的,并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。所以就可以 使用数组来做哈希表了, 因为数组都是 1000以内的。不要小瞧 这个耗时,在数据量大的情况,差距是很明显的。没有限制数值的大小,就无法使用数组来做哈希表了。
2023-07-11 11:29:37
28
原创 lec 242.有效的字母异位词
那看一下如何检查字符串t中是否出现了这些字符,同样在遍历字符串t的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。最后如果record数组所有元素都为零0,说明字符串s和t是字母异位词,return true。,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。时间复杂度为O(n),空间上因为定义是的一个常量大小的辅助数组,所以空间复杂度为O(1)。这样就将字符串s中字符出现的次数,统计出来了。再遍历 字符串s的时候,
2023-07-11 11:01:41
24
原创 lec 142.环形链表II
可以使用快慢指针法,分别定义 fast 和 slow 指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。那么fast指针走到环入口3的时候,已经走了k + n 个节点,slow相应的应该走了(k + n) / 2 个节点。可以看出如果slow 和 fast同时在环入口开始走,一定会在环入口3相遇,slow走了一圈,fast走了两圈。这是因为fast是走两步,slow是走一步,,所以fast一定可以和slow重合。
2023-07-11 10:33:25
31
原创 lec 160.链表相交
比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到交点。这里同学们要注意,交点不是数值相等,而是指针相等。为了方便举例,假设节点元素数值相等,则节点指针相等。简单来说,就是求两个链表交点节点的。否则循环退出返回空指针。
2023-07-11 09:49:22
36
原创 lec 19.删除链表的倒数第N个节点
双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。fast首先走n + 1步 ,为什么是n+1呢,因为只有这样同时移动的时候slow才能指向删除节点的上一个节点。首先这里我推荐大家使用虚拟头结点,这样方便处理删除实际头结点的逻辑。fast和slow同时移动,直到fast指向末尾(NULL)删除slow指向的下一个节点。
2023-06-30 16:31:35
35
原创 lec 24. 两两交换链表中的节点
建议使用虚拟头结点,这样会方便很多,要不然每次针对头结点(没有前一个指针指向头结点),还要单独处理。接下来就是交换相邻两个元素了,这道题目正常模拟就可以了。
2023-06-30 11:58:28
31
原创 lec 203 移除链表元素
这样原链表的所有节点就都可以按照统一的方式进行移除了。设置虚拟头节点后,return 头结点的时候,别忘了。, 这才是新的头结点。
2023-06-27 10:12:03
34
1
原创 lec 209 长度最小的子数组
不要以为for里放一个while就以为是O(n^2)啊, 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。滑动窗口也可以理解为双指针法的一种!窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。所以 只用一个for循环,那么这个循环的索引,一定是表示 滑动窗口的终止位置。
2023-06-27 07:35:01
27
1
原创 lec 977 有序数组的平方
这个时间复杂度是 O(n + nlogn), 可以说是O(nlogn)的时间复杂度,但为了和下面双指针法算法时间复杂度有鲜明对比,我记为 O(n + nlog n)。此时的时间复杂度为O(n),相对于暴力排序的解法O(n + nlog n)还是提升不少的。定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。此时可以考虑双指针法了,i指向起始位置,j指向终止位置。
2023-06-26 21:32:47
25
原创 lec 27 移除元素
这个题目暴力的解法就是两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组。很明显暴力解法的时间复杂度是O(n^2),这道题目暴力解法在leetcode上是可以过的。注意这些实现方法并没有改变元素的相对位置!
2023-06-26 21:07:48
48
原创 lec 704 二分查找
因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是。大家写二分法经常写乱,主要是因为。
2023-06-26 20:18:15
20
原创 备战C++
从以后开始记录我备战C++的笔记。打算分为八股和算法题两个部分。八股从侯捷老师的视频(已经看了一部分)开始,算法题打算从代码随想录开始。欢迎大家与我一起备战C++。
2023-06-26 18:28:32
30
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人