给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
思路
就……模拟?用了三个指针,时间O(n),空间O(1)
首先考虑如何交换两个节点,假设第一个节点为node
则:
- t = node->next //备份node的下一个节点
- node->next = node->next->next //让现节点的next指向改为下一节点的next
- t->next = node //下一节点的next指向现节点
交换完成
但已经在第二位置的现节点还不能丢弃,虽然它目前next指向3没什么错,但是它的next在下一轮swap后应该变为4,所以应该new一个变量来存储这种偶数节点
/**
* 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 = head->next;
ListNode* p = nullptr;
while(head != nullptr && head->next != nullptr){
ListNode* tmp = head->next;
head->next = tmp->next;
tmp->next = head;
p = head;
if(head->next != nullptr){
head = head->next;
if(head->next) p->next = head->next;
else p = head;
}
}
return newhead;
}
};
官方题解用的递归,参考一下:
class Solution {
public ListNode swapPairs(ListNode head) {
// 1. 终止条件:当前没有节点或者只有一个节点,肯定就不需要交换了
if (head == null || head.next == null) return head;
// 2. 调用单元
// 需要交换的两个节点是 head 和 head.next
ListNode firstNode = head;
ListNode secondNode = head.next;
// firstNode 连接后面交换完成的子链表
firstNode.next = swapPairs(secondNode.next);
// secondNode 连接 firstNode
secondNode.next = firstNode;
// 3. 返回值:返回交换完成的子链表
// secondNode 变成了头结点
return secondNode;
}
}