链表题简单题
链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针,适合动态插入和删除操作。
链表题简单题
链表简单题
面试题 02.03. 删除中间节点
1
2
3
4
5
void deleteNode(struct ListNode *node) {
// 转换成删除下一个节点
node->val = node->next->val;
node->next = node->next->next;
}
1290. 二进制链表转整数
1
2
3
4
5
6
7
8
9
10
int getDecimalValue(struct ListNode *head) {
struct ListNode *cur = head;
int res = 0;
while (cur != NULL) {
res <<= 1;
res += cur->val;
cur = cur->next;
}
return res;
}
面试题 02.02. 返回倒数第 k 个节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int kthToLast(struct ListNode *head, int k) {
struct ListNode *fast = head;
struct ListNode *slow = head;
// 快指针先走k步
while (k > 0) {
fast = fast->next;
k--;
}
// 快慢指针同时走
while (fast != NULL) {
fast = fast->next;
slow = slow->next;
}
return slow->val;
}
LCR 024. 反转链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 迭代
struct ListNode *reverseList(struct ListNode *head) {
struct ListNode *pre = NULL;
struct ListNode *next;
struct ListNode *cur = head;
// 原地反转
while (cur != NULL) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
1
2
3
4
5
6
7
8
9
10
// 递归
struct ListNode *reverseList(struct ListNode *head) {
// 递归出口
if (head == NULL || head->next == NULL) return head;
// 递归式
struct ListNode *newHead = reverseList(head->next); // 递归反转后面的链表
head->next->next = head; // 下个结点也就是反转后的尾节点,指向自己
head->next = NULL; // 自己作为新的尾节点
return newHead;
}
876. 链表的中间结点
1
2
3
4
5
6
7
8
9
10
11
// 返回向上取整的中间节点
struct ListNode *middleNode(struct ListNode *head) {
struct ListNode *fast = head;
struct ListNode *slow = head;
// 慢指针每走一步,快指针走两步
while (fast != NULL && fast->next != NULL) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
LCR 023. 相交链表
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
28
29
30
31
32
33
34
35
ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
ListNode* p = headA;
ListNode* q = headB;
while (p != nullptr && q != nullptr) {
p = p->next;
q = q->next;
}
// 先到结尾的是快指针
ListNode* slow, * fast;
if (p == nullptr) {
fast = headA;
slow = headB;
} else {
fast = headB;
slow = headA;
}
// 慢指针先走
while (p != nullptr) {
p = p->next;
slow = slow->next;
}
while (q != nullptr) {
q = q->next;
slow = slow->next;
}
while (slow != nullptr) {
if (slow == fast) return slow;
slow = slow->next;
fast = fast->next;
}
return nullptr;
}
面试题 02.01. 移除重复节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 散列
struct ListNode *removeDuplicateNodes(struct ListNode *head) {
if (head == NULL || head->next == NULL) return head;
int hash[20001]; // 记录是否出现过
memset(hash, 0, sizeof(hash));
struct ListNode *p = head;
hash[head->val] = 1;
// 判断当前下个节点是否需要删除
while (p != NULL && p->next != NULL) {
if (hash[p->next->val] == 0) {
// 首次出现
hash[p->next->val] = 1;
// 指针后移
p = p->next;
} else {
// 删除已经出现过
p->next = p->next->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
24
25
26
27
28
29
30
31
// 不用额外空间
// 删除链表中所有值为 k 的节点
struct ListNode *removeNode(struct ListNode *head, int k) {
struct ListNode *headNode = (struct ListNode *) malloc(sizeof(struct ListNode));
headNode->next = head;
struct ListNode *p = headNode;
while (p != NULL && p->next != NULL) {
if (p->next->val == k) {
// 跳过节点
p->next = p->next->next;
// 指针无需后移
} else {
// 指针后移
p = p->next;
}
}
return headNode->next;
}
struct ListNode *removeDuplicateNodes(struct ListNode *head) {
if (head == NULL || head->next == NULL) return head;
struct ListNode *cur = head;
while (cur != NULL && cur->next != NULL) {
// 删除后续链表中和当前值相同的所有节点
cur->next = removeNode(cur->next, cur->val);
cur = cur->next;
}
return head;
}
21. 合并两个有序链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 迭代
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode* p = list1;
ListNode* q = list2;
ListNode* dummy = new ListNode();
ListNode* cur = dummy;
while (p != nullptr && q != nullptr) {
if (p->val <= q->val) {
cur->next = p;
p = p->next;
} else {
cur->next = q;
q = q->next;
}
cur = cur->next;
}
cur->next = (p == nullptr) ? q : p;
return dummy->next;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 递归
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
if (list1 == nullptr) return list2;
if (list2 == nullptr) return list1;
ListNode* res, * other;
if (list1->val <= list2->val) {
res = list1;
other = list2;
} else {
res = list2;
other = list1;
}
res->next = mergeTwoLists(res->next, other);
return res;
}
LCR 027. 回文链表
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
ListNode* findMid(ListNode* head) {
ListNode* dummy = new ListNode();
dummy->next = head;
ListNode* slow = dummy;
ListNode* fast = dummy;
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
ListNode* reverse(ListNode* head) {
ListNode* next;
ListNode* pre = nullptr;
ListNode* cur = head;
while (cur != nullptr) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
// 后半段链表反转,然后和前半段逐个对比
bool isPalindrome(ListNode* head) {
ListNode* mid = findMid(head);
ListNode* other = reverse(mid->next);
mid->next = nullptr;
ListNode* cur = head;
while (other != nullptr) {
if (other->val != cur->val) return false;
other = other->next;
cur = cur->next;
}
return true;
}
203. 移除链表元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ListNode* removeElements(ListNode* head, int value) {
ListNode* dummy = new ListNode();
dummy->next = head;
ListNode* cur = head;
ListNode* pre = dummy;
while (cur != nullptr) {
if (cur->val == value) {
pre->next = cur->next;
} else {
pre = cur;
}
cur = cur->next;
}
return dummy->next;
}
83. 删除排序链表中的重复元素
1
2
3
4
5
6
7
8
9
10
11
12
ListNode* deleteDuplicates(ListNode* head) {
ListNode* pre = head;
ListNode* cur = head;
while (cur != nullptr) {
while (cur != nullptr && cur->val == pre->val) {
cur = cur->next;
}
pre->next = cur;
pre = pre->next;
}
return head;
}
141. 环形链表
1
2
3
4
5
6
7
8
9
10
11
12
13
bool hasCycle(struct ListNode *head) {
if (head == NULL || head->next == NULL) return false;
struct ListNode *slow = head;
struct ListNode *fast = head->next;
// 快慢指针,若有环,快指针迟早会追过慢指针(多跑了一个环的距离)
while (fast != NULL && fast->next != NULL) {
if (slow == fast) return true;
slow = slow->next;
fast = fast->next->next;
}
return false;
}
本文由作者按照 CC BY 4.0 进行授权