24.两两交换链表中的节点
点击查看代码
/*** 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* swapPairs(ListNode* head) {//有完整的一对,即两个链表节点才交换if(head == nullptr || head->next == nullptr) return head;ListNode *dummyhead = new ListNode(-1, head);ListNode *zero = dummyhead; //指向虚拟头节点ListNode *first = head; //指向第一个节点ListNode *second = head->next; //指向第二个节点while(1) {zero->next = second; //步骤一first->next = second->next; //步骤三second->next = first; //步骤二//有完整的一对,即两个链表节点才交换if(first->next == nullptr || first->next->next == nullptr) break; zero = first; //相当于新的虚拟头节点first = zero->next; //下一组中的第一个节点second = first->next; //下一组中的第二个节点}head = dummyhead->next;delete dummyhead;return head; }
};
将虚拟头节点、待交换的第一个节点、待交换的第二个节点视为一组,分别进行步骤一、步骤三、步骤二,然后判断下一轮是否有完整的一对,即两个可交换的链表节点,若有,则更新三个指针,分别指向新的虚拟头节点、待交换的第一个节点、待交换的第二个节点,然后进行重复操作
19.删除链表的倒数第N个节点
点击查看代码
/*** 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* removeNthFromEnd(ListNode* head, int n) {ListNode *dummyhead = new ListNode(-1, head);ListNode *slow = dummyhead, *fast = dummyhead;int count = 0;while(count++ < n+1) fast = fast->next; while(fast) {slow = slow->next;fast = fast->next;}ListNode *q = slow->next;slow->next = q->next;delete q;head = dummyhead->next;delete dummyhead;return head;}
};
核心思路:fast指针先走n+1步(注意,不是n,而是n+1,因为要找到倒数第n个节点的前驱节点),然后slow指针和fast指针一起往前走,直到fast指针走到nullptr,此时slow指针所指即为倒数第n个节点的前驱节点
本题所给提示中,1 <= n <= size,故不会出现n非法的情形,无需作特殊处理,一趟扫描即可完成。
160.相交链表
解法一:
点击查看代码
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode *p_A = headA, *p_B = headB;int size_A = 0, size_B = 0;while(p_A) { //求A链表长度++size_A;p_A = p_A->next;}while(p_B) { //求B链表长度++size_B;p_B = p_B->next;}int count = abs(size_B - size_A); //求A、B链表长度差p_A = headA, p_B = headB;while(count-- > 0) { //长链表的指针先走count步,走完后长短链表指针一起走if(size_A > size_B) p_A = p_A->next;else p_B = p_B->next;}while(p_A) { //长短链表指针一起走,若有相交节点,必能同时到达相交节点处if(p_A == p_B) return p_A;p_A = p_A->next;p_B = p_B->next;}return nullptr; //前面都没返回,说明没有相交节点}
};
点击查看代码
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode *p_A = headA, *p_B = headB;int count_A = 0, count_B = 0;while(p_A && p_B) {if(p_A == p_B) return p_A;if(p_A->next == nullptr) {if(count_A == 0){p_A = headB;++count_A;}else return nullptr;}else p_A = p_A->next;if(p_B->next == nullptr) {if(count_B == 0){p_B = headA;++count_B;}else return nullptr;}else p_B = p_B->next;}return nullptr;}
};
解法二核心思想:p_A走完A链表后走B链表,p_B走完B链表后走A链表,若有相交节点,必然能同时到达相交节点处,若无相交节点,二者必然同时第二次遇到nullptr,故需要count_A和count_B分别记录p_A和p_B是第几次遇到nullptr,count = 0时为第一次遇到,切换另一个链表遍历,若count = 1则为第二次遇到,此时说明必然无相交节点,直接返回nullptr
142.环形链表Ⅱ
有点懵,后续解决...
2025/02/16