/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    ListNode* swapPairs(ListNode* head) {
        // write code here

//纯手搓逻辑
#if 0 
        if(!head || !head->next) return head;
        ListNode* start = head->next;  //记录第一组的第二个节点,也就是交换后的头节点
        ListNode* pfront = nullptr; //表示前一个二元组指向后一个二元组的那个节点的指针;
        while (head && head->next)
        {
            ListNode* headNext = head->next; //两个一组,记录第二个节点
            head->next = head->next->next;  //第一个节点指向第三个节点
            headNext->next = head; //第二个阶段指向第一个节点
            if(pfront)
            {
                pfront->next = headNext; //修改前一个二元组指向后一个二元组的节点
            }
            pfront = head;
            head = head->next; //本组处理完毕,第一个节点指向第三个节点
        }

        return start;
#endif 

//直接交换节点数值
#if 0
        ListNode* startNode = head;
        while (head && head->next)
        {
            int tempVal = head->val;
            head->val = head->next->val;
            head->next->val = tempVal;
            head = head->next->next;
        }

        return startNode;
#endif

//递归调用
//从最内层往最外层思考

        //最内层应该给外面返回什么节点?组不成对时返回当前的头节点
        if(!head || !head->next)
        {
            return head;
        }
        //能组成队时返回当前的第二个节点的指针
        ListNode* secondNode = head->next;
        //中间层该怎么获取到后一层的指针? 把下一个数据对的头节点传下去
        head->next = swapPairs(secondNode->next);
        secondNode->next = head;
        return secondNode;
    }
};

归纳三种解法,三种思路;第一种纯推理;第二种比较巧妙;第三种从最内层数据对思考,结合中间层数据对,完善代码逻辑。