24 两两交换链表中的节点(力扣:https://leetcode.cn/problems/swap-nodes-in-pairs/
条件:成对交换链表节点(而不是其中的值)剩余单数或null时退出,最后返回新head(空/单节点链表返回原head)
Tips:
- 由于可交换情景下需要指定原第二个节点为新头节点、空和单节点链表不需要更换头节点,所以使用虚拟头统一处理(虚拟头next指向原head且return 虚拟头next),把修改丢给后面的循环判断;
- 遍历指针只操作遍历和交换,所以需要定义另一个prevTail指针衔接变化后的两对节点;
- 交换时易混淆遍历和衔接指针的指向,建议使用first和second保证逻辑清楚,此外交换时修改的都是first或者second的next而非first本身地址,所以prevTail可以在交换后指向first不用担心地址丢失或者指向被修改的地址;
点击查看代码
/*** 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) {//虚拟头记住未来新head的地址,不管需不需要移位,最后return dummyhead->next即可ListNode* dummyHead = new ListNode();dummyHead->next = head;//ListNode* dummyHead = head->next;//遍历用指针ListNode* current = head;//衔接切换前后两对节点ListNode* prevTail = dummyHead;//非空链表、单节点链表、后续待处理的为偶数while(current != nullptr && current->next != nullptr){ListNode* first = current;ListNode* second = current->next;ListNode* nextCurrent = current->next->next;//2->1second->next = first;//1->3first->next = nextCurrent;//让上组的结尾指向新头,链接两个组prevTail->next = second;//越过12从3开始current = nextCurrent;//这里prevend更新成上一对的新尾部(第一次循环里是1)prevTail = first;}return dummyHead->next;}
};