【中等】24-两两交换链表中的节点 Swap Nodes in Pairs
题目
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/swap-nodes-in-pairs
解法
解题思路
对于一个链表,想要两两翻转,可以划分为将链表中的某个长度为2的子链翻转过来并且连接上的子问题
对于子链反转,由于长度是2,只需要让后面的节点指向前面节点即可,而对于子链连接回原链的问题,我们只需要将断开部分的前驱节点与原子链的末尾节点连接,断开部分的后驱节点与原子链的前方节点连接即可,也就是说,对于一个子问题,我们关注的是子链开始,子链结束,子链前驱,子链后驱四个节点
一个子问题解决了,我们分析一共有多少子问题,很简单,对于长度为n的链表,一共需要解决n/2个子问题,从前到后,
-
每一个子问题的子链开始是前一个子问题的子链后驱
-
每一个子问题的子链结束时子链开始位置的后第t-1位
-
每一个子问题的子链前驱是上一个子问题的子链结束位置
-
每一个子问题的子链后驱是当前子链结束的下一个节点
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void swap(ListNode* before, ListNode *start, ListNode* end, ListNode* back){
before->next = end;
end->next = start;
start->next = back;
}
ListNode* swapPairs(ListNode* head) {
if(head == NULL or head->next == NULL) return head;
ListNode *res = new ListNode(0);
res->next = head;
ListNode* before = res, *start = head, *end = head->next;
ListNode *back = end->next;
while(end!=NULL){
swap(before, start, end, back);
if(back == NULL) return res->next;
before = start;
start = back;
end = back->next;
for(int i = 0; i < 2; ++i){
if(back == NULL) return res->next;
back = back->next;
}
}
return res->next;
}
};
Email:1252418308@qq.com