描述

给你一个链表,请你两两交换相邻节点,你需要真正交换节点本身,而不是修改节点的值。
两两交换示例:
链表    :1->2->3->4     交换后 :2->1->4->3


链表    :1->2->3     交换后: 2->1->3
数据范围:链表长度满足  , 链表上的值满足 

问题分析: 两两交换节点,其实跟链表k个一组翻转类似。只不过这里的k=2.那么我们就不需要编写反转链表函数。也没必要采用反转的方法来做。

记录一个当前需要交换位置的前驱pre, 假设当前位置为head,开始进行操作前,再记录一个后驱p=head->next->next,
然后做下面的操作:pre->next=head->next,pre->next->next=head,head->next=p,pre=head(作为新的前驱),head=head->next。
具体过程看下面代码:
复杂度分析:
时间复杂度O(n):整个过程只需要遍历一遍链表就完成了。
空间复杂度O(1):只定义了一个指针和新创建了一个节点。
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
    ListNode* swapLinkedPair(ListNode* head) {
        if(head==NULL||head->next==NULL) return head;
        //因为头节点没有前驱,所以需要创建一个新节点
        ListNode *Nhead=(ListNode*)malloc(sizeof(ListNode));
        Nhead->next=head;
        ListNode *p,*pre;
        pre=Nhead;
        while(head->next!=NULL&&head!=NULL) {
            //因为下面操作会改变指针指向,所以需要用p提前记录下一个需要交换的位置
            p=head->next->next;
            pre->next=head->next;
            pre->next->next=head;
            head->next=p;
            pre=head;//作为下一个需要交换的前驱
            head=head->next;
        }
        return Nhead->next;
    }
};