链表是数据结构面试中的高频考点,掌握其操作技巧至关重要。下面整理了五道经典题目,涵盖模拟、指针操作、堆与分治等核心思路。
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* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* cur1 = l1, *cur2 = l2;
ListNode* newhead = new ListNode(0); // 虚拟头结点
ListNode* head = newhead; // 尾指针
int t = 0; // 记录进位
while(cur1 || cur2 || t){
if(cur1){
t += cur1->val;
cur1 = cur1->next;
}
if(cur2){
t += cur2->val;
cur2 = cur2->next;
}
ListNode* tmp = new ListNode(t % 10);
head->next = tmp;
head = head->next;
t /= 10;
}
head = newhead->next;
delete newhead;
return head;
}
};
2. 两两交换链表中的节点
思路分析: 通过画图辅助理解指针指向会更直观。这里使用虚拟头结点简化边界处理,注意交换时指针断链和重连的顺序,避免死循环或丢失节点。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
(!head || !head->next) head;
ListNode* newhead = (, head);
ListNode* prev = newhead, *cur = newhead->next;
ListNode* next = cur->next, *nnext = cur->next->next;
(cur && next){
prev->next = next;
cur->next = nnext;
next->next = cur;
prev = cur;
cur = nnext;
(cur) next = cur->next;
(next) nnext = next->next;
}
head = newhead->next;
newhead;
head;
}
};

