链表:数组相关
# 0002. 两数相加 (opens new window)
题目
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
2
3
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
2
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
2
提示:
- 每个链表中的节点数在范围
[1, 100]
内 0 <= Node.val <= 9
- 题目数据保证列表表示的数字不含前导零
按位模拟加法,注意循环条件不要忘记 || sum
。
代码
# 0021. 合并两个有序链表 (opens new window)
题目
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
2
示例 2:
输入:l1 = [], l2 = []
输出:[]
2
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
2
提示:
- 两个链表的节点数目范围是
[0, 50]
-100 <= Node.val <= 100
l1
和l2
均按 非递减顺序 排列
同时遍历两个链表,从中选取较小的元素添加到结果链表,直至两个链表都遍历完成。
代码
# 0147. 对链表进行插入排序 (opens new window)
题目
给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。
定义一个虚拟头结点,用于存储已排序列表,遍历原始链表,每遇到一个结点,就将其插入到已排序链表中,最后返回虚拟头结点的下一个结点即可。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
ListNode *dummy = new ListNode(0), *cur = head;
while (cur) {
ListNode *prev = dummy, *next = cur->next;
while (prev->next && prev->next->val <= cur->val) {
prev = prev->next;
}
cur->next = prev->next;
prev->next = cur;
cur = next;
}
return dummy->next;
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 0148. 排序链表 (opens new window)
题目
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
进阶:你可以在 O(nlogn) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
由于题目要求时间复杂度为 O(nlogn),空间复杂度为 O(1),所以需要采用自底向上的归并排序。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
int n = 0;
for (ListNode* cur = head; cur; cur = cur->next) n++;
for (int i = 1; i < n; i *= 2) {
ListNode *dummy = new ListNode(0), *cur = dummy;
int cnt = ceil(1.0 * n / (2 * i));
while (cnt--) {
ListNode *p = head, *q = head;
for (int j = 0; j < i && q; j++) q = q->next;
ListNode *next = q;
for (int j = 0; j < i && next; j++) next = next->next;
int l = 0, r = 0;
while (l < i && r < i && p && q) {
if (p->val <= q->val) cur = cur->next = p, p = p->next, l++;
else cur = cur->next = q, q = q->next, r++;
}
while (l < i && p) cur = cur->next = p, p = p->next, l++;
while (r < i && q) cur = cur->next = q, q = q->next, r++;
head = next;
}
cur->next = nullptr;
head = dummy->next;
}
return head;
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 0160. 相交链表 (opens new window)
题目
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
解析
走到尽头见不到你,于是走过你来时的路,等到相遇时才发现,你也走过我来时的路。—— LeetCode 评论区
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* pA = headA;
ListNode* pB = headB;
while (pA != pB) {
pA = pA ? pA->next : headB;
pB = pB ? pB->next : headA;
}
return pA;
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 0369. 给单链表加一 (opens new window)
题目
用一个 非空 单链表来表示一个非负整数,然后将这个整数加一。
你可以假设这个整数除了 0 本身,没有任何前导的 0。
这个整数的各个数位按照 高位在链表头部、低位在链表尾部 的顺序排列。
解析
找出最靠右的不是 9 的数字,将该数字加 1。然后将该数字之后所有的 9 改成 0。
注意
最后返回头结点时需要判断 dummy 结点是否被赋值,即:999 + 1 = 1000 会导致链表长度改变。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* plusOne(ListNode* head) {
ListNode* dummy = new ListNode(0);
dummy->next = head;
ListNode* lastNotNine = dummy;
ListNode* cur = dummy;
while (cur) {
if (cur->val != 9) {
lastNotNine = cur;
}
cur = cur->next;
}
++lastNotNine->val;
cur = lastNotNine->next;
while (cur) {
cur->val = 0;
cur = cur->next;
}
return dummy->val ? dummy : head;
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35