两两交换链表中的节点
24. 两两交换链表中的节点24. 两两交换链表中的节点 - 力扣(LeetCode)
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
思路这道题目正常模拟就可以了。
建议使用虚拟头结点,这样会方便很多,要不然每次针对头结点(没有前一个指针指向头结点),还要单独处理。
做题时候记得先画图,按照图中指针指向的链路写代码就行。使用虚拟头节点的话,这个过程简单很多。注意一下,在交换完一次节点后,需要把虚拟头节点向后移动!一定要移动!
以下是c++实现代码:
12345678910111213141516171819202122232425262728293031/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : ...
设计链表
707.设计链表力扣
题意:
在链表类中实现这些功能:
get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
思路链表的增删查改实现。与之前学的数据结构链表学习不太一样。当时写了链表的创建、删除,认为增加和修改操作大同小异,就没有实践。知道做了这一题,才发现了许多没注意的细节问题。
链表问题,可以用数组、双指针的思路来解决。
数组算是暴力解,先把链表中的值存在数组中,然后按照 规定取 ...
翻转链表
206.反转链表力扣
题意:反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
思路使用双指针法做。注意使用双指针法的时候,不要改变元素的位置,可以添加额外的指针来凑双指针。若改变元素位置来做,容易陷入死循环,导致做错。
C语言代码如下:
12345678910111213141516171819202122/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ /* pre cur cur->next */struct ListNode* reverseList(struct ListNode* head) { struct ListNode* cur; struct ListNode* temp; struct ListNo ...
移除链表元素
203.移除链表元素203. 移除链表元素 - 力扣(LeetCode)
题意:删除链表中等于给定值 val 的所有节点。
示例 1: 输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]
示例 2: 输入:head = [], val = 1 输出:[]
示例 3: 输入:head = [7,7,7,7], val = 7 输出:[]
思路随想录中使用两种方法移除链表元素。直接删除的方法如下。
2023.3.14补充:后续补充虚拟头节点的做法。假设一个虚拟头节点,指向head,通过虚拟头节点的不断移动来寻找相同的元素。此过程head没有变化。
做的过程中,直接删除的方法的难点在于:
如何返回头节点。
如何把元素从上一个节点链接到下一个节点。
C语言实现如下:
1234567891011121314151617181920212223//法一 判断链表头结点是否为目标值,不是的话去掉struct ListNode* removeElements(struct ListNode* ...
C语言学习笔记
malloc函数C语言中malloc是动态内存分配函数,C++中使用new关键字函数原型:void *malloc(unsigned int num_bytes);
void *malloc(sizeof() * n);
表示从堆山动态获取[sizeof()*n] 大小的空间,
其中,void*是泛指的指针类型。可以转换为任意指针类型的参数,一般与sizeof中的类型一致。例如:
int* p = (int*) malloc(sizeof(int) * n);
参数:num_bytes 是无符号整型,用于表示分配的字节数。返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。void 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据。功能:分配长度为num_bytes字节的内存块注意:当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。关于该函数 ...
螺旋矩阵
59.螺旋矩阵II59. 螺旋矩阵 II - 力扣(LeetCode)
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
难点二维数组的构造,以及模拟过程的逻辑掌控。
C语言构建数组较为麻烦,C++则可以利用容器来构造数组。
还需要多复习多用C语言如何使用指针构造二维数组。
思路这道题目可以说在面试中出现频率较高的题目,本题并不涉及到什么算法,就是模拟过程,但却十分考察对代码的掌控能力。
本题依然是要坚持循环不变量原则。
模拟顺时针画矩阵的过程:
填充上行从左到右
填充右列从上到下
填充下行从右到左
填充左列从下到上
由外向内一圈一圈这么画下去。
可以发现这里的边界条件非常多,在一个循环中,如此多的边界条件,如果不按照固定规则来遍历,那就是一进循环深似海,从此offer是路人。
这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。
二维 ...
有序数组的平方
977.有序数组的平方力扣链接
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
思路暴力排序最直观的想法,莫过于:每个数平方之后,排个序。本人于2024年3月9号尝试用c语言写过,奈何忘了排序算法该怎么写。以下C++代码抄自网上,有时间需要复习常见排序算法。C++实现代码如下:
12345678910class Solution {public: vector<int> sortedSquares(vector<int>& A) { for (int i = 0; i < A.size(); i++) { ...
长度最小的子数组
209.长度最小的子数组力扣链接
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
提示:
1 <= target <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5
思路暴力解法 使用两个for循环,然后不断的寻找符合条件的子序列,时间复杂度是O(n^2)。暴力解法在2024年3月10日没有试过。代码如下(copy至其他网友):
123456789101112131415161718192021class Solution {public: int minSubArrayLen(int s, vector<int>& n ...
移除元素
27. 移除元素力扣链接
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 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。
你不需要考虑数组中超出新长度后面的元素。
思路数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
暴力解法这个题目暴力的解法就是两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组。
删除过程如下:
123456789101112int removeElement(int ...
二分查找
704. 二分查找力扣链接
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
123输入: nums = [-1,0,3,5,9,12], target = 9 输出: 4 解释: 9 出现在 nums 中并且下标为 4
123
示例 2:
123输入: nums = [-1,0,3,5,9,12], target = 2 输出: -1 解释: 2 不存在 nums 中因此返回 -1
123
提示:
你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。
思路这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。
二 ...