Given a linked list, swap every two adjacent nodes and return its head.

For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* swapPairs(struct ListNode* head)
{
    if(NULL == head)
        return NULL;
    /*tmp:exchange the value*/
    int tmp = 0;
    struct ListNode *p = head;
    struct ListNode *pnext = p->next;
    
    while(p&&pnext)
    {
        /*exchange p and pnext*/
        tmp = p->val;
        p->val = pnext->val;
        pnext->val = tmp;
        
        /*prepare for next loop*/
        p = pnext->next;
        /*p not null,then use p->next*/
        if(p)
            pnext = p->next;
    }
    
    return head;
    
}

上面解法实际上和下面的解法一样,下面这个解法更加精炼:

/**
 * 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) {
        ListNode * p = head;
        while(p && p->next)
        {
            swap(p->val,p->next->val);
            p = p->next->next;
        }
        
        return head;
    }
};

但是题目中明确有要求:Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.不能更改结点中的值,我们上面这两种解法都修改了结点的值。
一种比较巧妙的解法是:

/**
 * 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) 
    {
        ListNode **pp = &head,*p,*pnext;
        while((p =*pp) && (pnext = p->next))
        {
            p->next = pnext->next;
            pnext->next = p;

            *pp = pnext;
            pp = &(p->next);
        }
        
        return head;
    }
};

一个可以调试运行的完整程序如下,方便理解上面的代码:

#include <iostream>
using namespace std;

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) {}
 };

ListNode* swapPairs(ListNode* head) {
    //p point to current node,pnext point the next node of p
    //pp point to the current start node,including deal with the actual head after swap(first loop)
    ListNode **pp = &head,*p,*pnext;
    while((p=*pp) && (pnext=p->next))
    {
        //swap the node p & pnext
        p->next = pnext->next;
        pnext->next = p;
        //modify the start node,pointer to pointer ,so we can change pointer itelf
        //if we remove line *pp = pnext,we will lost 2 4 in {1,2,3,4}
        *pp = pnext;
        pp=&(p->next);
    }
    
    for(ListNode *it = head;it != NULL;it=it->next)
    {
        cout<<it->val<<endl;
    }

    return head;
}

int main()
{
    ListNode last(4);
    ListNode third(3,&last);
    ListNode second(2,&third);
    ListNode first(1,&second);
    swapPairs(&first);

    return 0;
}

2021.07.07更新:
一种比较好理解的写法:

/**
 * 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) {
        ListNode* dummy = new ListNode(-1);
        dummy->next = head;
        ListNode* node = dummy;
        int i = 0;

        while(head && head->next)
        {
            ListNode* first = head;
            ListNode* second = head->next;
            
            //第一个结点指向第二节点下一个元素
            first->next = second->next;

            //第二个结点指向下一个结点
            second->next = first;

            //串联链表
            node->next = second;
            node = first;

            //交换之后head每次只需更新为head->next
            head = head->next;
        }
        return dummy->next;
    }
};