代码随想录复习
本周对于之前跟随视频学习的一些力扣题目进行了一个复习.所以本博客主要记录本周复习题目时出现问题的题目。
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]
这道题目主要考察的是一个双指针问题,我们可以通过左右指针向中间位移实现一个添加最大值。
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
int* array = (int*)malloc(sizeof(int) * numsSize);
int i = 0;
int j = numsSize - 1;
int k = numsSize - 1;
while (i <= j) {
if (nums[i] * nums[i] < nums[j] * nums[j]) {
array[k--] = nums[j] * nums[j];
j--;
}
else {
array[k--] = nums[i] * nums[i];
i++;
}
}
*returnSize = numsSize;
return array;
}
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
这道题目主要是一个滑动窗口的实现,也同样是一个双指针的移动实现一个数组求和。
int minSubArrayLen(int target, int* nums, int numsSize) {
int* array = (int*)malloc(sizeof(int) * numsSize);
int sum = 0;
int i = 0;
int j = 0;
int cnt = numsSize + 1;
for(; i < numsSize; i++) {
sum += nums[i];
while (sum >= target) {
if (i - j + 1 < cnt) {
cnt = i - j + 1;
}
sum -= nums[j];
j++;
}
}
if (cnt == numsSize + 1) {
return 0;
}
return cnt;
}
206.反转链表
题意:反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
反转链表的实现方式主要还是两种,一种是用迭代的方式,另一种则通过递归的方式。递归的方式,是在归的过程中实现一个节点的修改。
struct ListNode* reverseList(struct ListNode* head) { //递归的方式
if (head == NULL || head->next == NULL) { //找到最后一个节点返回
return head;
}
struct ListNode* cur = reverseList(head->next); //保存头节点
head->next->next = head;
head->next = NULL;
return cur;
}
struct ListNode* reverseList(struct ListNode* head) { //迭代的方式
struct ListNode* pre = NULL;
struct ListNode* cur = head;
struct ListNode* tmp;
while (cur) {
tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
142.环形链表II
题意: 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
这道题目主要考的二指针主要通过一个数学公式实现一个查找到入口的功能。
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* fast = head;
struct ListNode* slow = head;
struct ListNode* index1 = head;
struct ListNode* index2 = head;
while(fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
index1 = fast;
index2 = head;
while (index1 != index2) {
index1 = index1->next;
index2 = index2->next;
}
return index2;
}
}
return NULL;
}
完成上述链表后,我做了一道结合多种链表操作的题目,来巩固我的链表的算法操作。143.重排链表
143.重排链表
给定一个单链表 L
的头节点 head
,单链表 L
表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
这道题目主要是结合了链表的三个核心操作,1.寻找中间节点。2.反转链表。3.合并链表。我们找到中间链表,让后将后半部分反转,然后再把后半部分和前半部分进行一个链表合并的操作.
struct ListNode* mid(struct ListNode* head) {
struct ListNode* dummyhead = (struct ListNode*)malloc(sizeof(struct ListNode));
dummyhead->next = head;
struct ListNode* fast = dummyhead;
struct ListNode* slow = dummyhead;
while (fast != NULL && fast->next != NULL ) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
struct ListNode* rev(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* cur = rev(head->next);
head->next->next = head;
head->next = NULL;
return cur;
}
void mergeList(struct ListNode* l1, struct ListNode* l2) {
struct ListNode* l1_tmp;
struct ListNode* l2_tmp;
while (l1 != NULL && l2 != NULL) {
l1_tmp = l1->next;
l2_tmp = l2->next;
l1->next = l2;
l1 = l1_tmp;
l2->next = l1_tmp;
l2 = l2_tmp;
}
}
void reorderList(struct ListNode* head) {
if (head == NULL || head->next == NULL || head->next->next == NULL) {
return;
}
struct ListNode* mid_node = mid(head);
struct ListNode* reversed_mid = rev(mid_node->next);
mid_node->next = NULL;
mergeList(head, reversed_mid);
}