链表编程题通常涉及对链表的操作,包括插入、删除、查找、反转等。解决这类问题的关键在于理解链表的基本结构和操作原理。以下是一些常见链表编程题的解题思路和代码示例:
1. 删除链表中所有等于给定值的节点
思路:遍历链表,找出需要删除的节点,并将其前一个节点的`next`指针指向需要删除节点的下一个节点,从而释放需要删除的节点。如果需要删除的是头节点,则直接将头节点指向下一个节点。
```c
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode* cur = head;
struct ListNode* prev = NULL;
while (cur) {
if (cur->val == val) {
if (cur == head) {
head = cur->next;
free(cur);
cur = head;
} else {
prev->next = cur->next;
free(cur);
cur = prev->next;
}
} else {
prev = cur;
cur = cur->next;
}
}
return head;
}
```
2. 删除链表中所有介于给定两个值之间的节点
思路:遍历链表,找出需要删除的节点,并将其前一个节点的`next`指针指向需要删除节点的下一个节点,从而释放需要删除的节点。
```c
struct ListNode* removeElementsBetween(struct ListNode* head, int val1, int val2) {
struct ListNode* dummy = new ListNode(0);
dummy->next = head;
struct ListNode* prev = dummy;
struct ListNode* cur = head;
while (cur) {
if (cur->val > val2) {
break;
} else if (cur->val >= val1) {
prev->next = cur->next;
free(cur);
} else {
prev = cur;
}
cur = cur->next;
}
head = dummy->next;
delete dummy;
return head;
}
```
3. 反转链表
思路:使用三个指针,分别指向当前节点、前一个节点和后一个节点。通过不断调整指针的指向,实现链表的反转。
```c
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* prev = NULL;
struct ListNode* curr = head;
struct ListNode* next = NULL;
while (curr) {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
```
4. 合并两个有序链表
思路:创建一个新的链表,依次将两个链表中的节点插入到新链表中,保持新链表的有序性。
```c
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
struct ListNode dummy;
struct ListNode* tail = &dummy;
while (l1 && l2) {
if (l1->val < l2->val) {
tail->next = l1;
l1 = l1->next;
} else {
tail->next = l2;
l2 = l2->next;
}
tail = tail->next;
}
tail->next = l1 ? l1 : l2;
return dummy.next;
}
```
5. 判断链表是否有环
思路:使用快慢指针法,快指针每次走两步,慢指针每次走一步。如果链表有环,快指针最终会追上慢指针。
```c
bool hasCycle(struct ListNode* head) {
struct ListNode* slow = head;
struct ListNode* fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
return true;
}
}
return false;
}
```
6. 找出链表的中间节点
思路:使用快慢指针法,快指针每次走两步,慢指针每次走一步。当快指针走到链表末尾时,慢指针指向链表的中间节点。