链表:删除
睡不醒的鲤鱼 2021-06-24 每日一题 LeetCode
# 0019. 删除链表的倒数第 N 个结点 (opens new window)
题目
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
1
2
2
示例 2:
输入:head = [1], n = 1
输出:[]
1
2
2
示例 3:
输入:head = [1,2], n = 1
输出:[1]
1
2
2
提示:
- 链表中结点的数目为
sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
进阶:你能尝试使用一趟扫描实现吗?
快慢双指针,令快指针先走 n 步,之后两指针再同步移动,直到快指针移动到链表结尾,此时慢指针指向的下一个位置即为要删除元素。
注意
- 在头部插入一个虚拟结点,可以避免对头结点的特殊处理。
- 边界情况可以测试几个 case 确定。
代码
# 0082. 删除排序链表中的重复元素 II (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* deleteDuplicates(ListNode* head) {
ListNode *dummy = new ListNode(0), *p = dummy;
dummy->next = head;
while (p->next) {
ListNode *q = p->next;
while (q->next && q->next->val == q->val) q = q->next;
if (q == p->next) p = p->next;
else p->next = q->next;
}
return dummy->next;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 0083. 删除排序链表中的重复元素 (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* deleteDuplicates(ListNode* head) {
ListNode *p = head;
while (p && p->next) {
ListNode *q = p->next;
while (q && q->val == p->val) q = q->next;
p->next = q;
p = p->next;
}
return head;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 0203. 移除链表元素 (opens new window)
题目
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
解析
由于头结点可能被删除,因此增加一个虚拟结点,遍历链表,当 next 结点值为 val 时,跳过该结点,直至链表结尾。
代码
/**
* 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* removeElements(ListNode* head, int val) {
ListNode* dummy = new ListNode(0);
dummy->next = head;
ListNode* p = dummy;
while (p->next) {
if (p->next->val == val) {
p->next = p->next->next;
} else {
p = p->next;
}
}
return dummy->next;
}
};
1
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
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
# 0237. 删除链表中的节点 (opens new window)
题目
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点。传入函数的唯一参数为要被删除的节点。
解析
由于本题没有给出链表的头节点,可以换一种思路,将下一个节点的 val 复制到被删除节点上,同时被删除节点指向下下个节点。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
node->val = node->next->val;
node->next = node->next->next;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15