24. 两两交换链表中的节点
之前写过一次,很容易写出来。记得设置虚拟头。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyhead = new ListNode(0);
ListNode* cur = dummyhead;
dummyhead->next = head;
while (cur->next && cur->next->next) {
ListNode* temp1 = cur->next;
ListNode* temp2 = cur->next->next;
ListNode* temp3 = cur->next->next->next;
cur->next = temp2;
temp2->next = temp1;
temp1->next = temp3;
cur = cur->next->next;
}
return dummyhead->next;
}
};
19.删除链表的倒数第N个节点
参考资料:代码随想录 (programmercarl.com)
注意点:要想删除该节点,必先知道该节点的前驱节点才能删除。
思路:设置虚拟头节点,使用双指针,要想删除倒数第n个节点,先让fast指针移动n+1个节点,再让快慢指针同时移动,当fast指针移动到尾节点时,slow指针正好移动到要删除的节点的前一个节点,然后删除该节点。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyhead = new ListNode(0);
dummyhead->next = head;
ListNode* fast = dummyhead;
ListNode* slow = dummyhead;
while (n-- && fast) {
fast = fast->next;
}
fast = fast->next;
while (fast) {
fast = fast->next;
slow = slow->next;
}
ListNode* temp = slow->next;
slow->next = slow->next->next;
delete temp;
return dummyhead->next;
}
};
面试题 02.07. 链表相交
思路:先尾对齐两个链表,然后一起遍历,直到找到相交节点。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
int lenA = 0;
while (curA) {
curA = curA->next;
lenA++;
}
ListNode* curB = headB;
int lenB = 0;
while (curB) {
curB = curB->next;
lenB++;
}
int len = 0;
curA = headA;
curB = headB;
if (lenA < lenB) {
swap(curA, curB);
swap(lenA, lenB);
}
len = lenA - lenB;
while (len--) {
curA = curA->next;
}
while (curA) {
if (curA == curB) {
return curA;
}
curA = curA->next;
curB = curB->next;
}
return NULL;
}
};
142.环形链表II
还没完全掌握,先照着打了一遍。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (fast == slow) {
ListNode* B = fast;
ListNode* A = head;
while (A != B) {
B = B->next;
A = A->next;
}
return A;
}
}
return NULL;
}
};
总结
链表还是很有难度的,要加把劲。