题目描述
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
题目链接: https://leetcode-cn.com/problems/swap-nodes-in-pairs/
思路
保存4个指针:当前节点curNode,当前节点的前一个节点preNode,当前节点的下一个节点nextNode(防止链表断掉),当前节点的下一个节点的下一个节点temp。创建一个新的链表头指向原来的head,然后将nextNode->next=curNode,curNode->next=temp,preNode->next=nextNode,这样交换了两个节点,然后将preNode更新为curNode,curNode更新为temp。重复这一过程,直至curNode为空。代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(head==nullptr || head->next==nullptr){
return head;
}
ListNode* newHead = new ListNode(0); //新的链表头
newHead->next = head;
ListNode* curNode = head;
ListNode* preNode = newHead;
ListNode* nextNode = nullptr;
while(curNode!=nullptr){
nextNode = curNode->next;
if(nextNode==nullptr){ // 链表中有奇数个节点,最后一个不交换
break;
}
ListNode* temp = nextNode->next;
nextNode->next = curNode;
preNode->next = nextNode;
curNode->next = temp;
preNode = curNode;
curNode = temp;
}
return newHead->next;
}
};
也可以这样写:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(head==nullptr) return head;
if(head->next==nullptr) return head;
ListNode* dummy = new ListNode(0);
dummy->next = head;
ListNode* pre = dummy;
ListNode* curNode = head;
while(curNode!=nullptr && curNode->next!=nullptr){
ListNode* nextNode = curNode->next;
curNode->next = nextNode->next;
nextNode->next = curNode;
pre->next = nextNode;
pre = curNode;
curNode = curNode->next;
}
return dummy->next;
}
};
基本是一样的,就把循环条件改了一下。
- 时间复杂度: O(n)
- 空间复杂度:O(1)
总结
这个题和翻转链表有点类似,交换两个节点实际上就是将nextNode->next指向curNode,这样的话最初nextNode指向的节点会丢失,链表会断掉。为了解决这个问题,需要一个变量保存nextNode最初指向的节点,在操作的过程中,可以画图模拟一下,找到模式。