[leetcode刷题笔记] 两两交换链表中的节点

题目地址: https://leetcode-cn.com/problems/swap-nodes-in-pairs/
题目内容: 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换

示例:

给定 1->2->3->4, 你应该返回 2->1->4->3.

分析:
利用递归的思路,可以分为三步去考虑整个过程,假设函数原型为ListNode* swapPairs(ListNode* head)

  1. 将前两个节点进行交换,并返回交换后的头节点,这个时候如果节点数量不足两个,则直接返回头指针,将返回记作hand;
  2. 递归,调用swapPairs(head->next->next),将后面的节点对进行交换,注意到返回的应该是后面的交换过的头节点。将返回记作next;
  3. 将第一个和第二个拼接起来,有hand->next->next = next

储存整个链表的数据结构如:

  struct ListNode {
      int val;
      ListNode *next;
      ListNode(int x) : val(x), next(NULL) {}
  };

代码如:

class Solution {
public:
    ListNode* swap(ListNode *pleft, ListNode *pright){
        pleft->next = pright->next;
        pright->next = pleft;
        return pright;
    }
    ListNode* swapPairs(ListNode* head) {
        if (head && head->next){
            ListNode* hand = swap(head, head->next);
            ListNode *next = swapPairs(hand->next->next);
            hand->next->next = next;
            return hand;
        }
        else {
            return head;
        }
    }
};

为了效率,可以把交换函数swap()进行内联,变成:

inline ListNode* swap(ListNode *pleft, ListNode *pright){
	       pleft->next = pright->next;
	       pright->next = pleft;
	       return pright;
   }

基于迭代的方法,主要要注意不同循环之间,需要用一个concat变量进行拼接,才不至于断链,代码如:

class Solution {
public:
    inline ListNode* swap(ListNode *pleft, ListNode *pright){
        pleft->next = pright->next;
        pright->next = pleft;
        return pright;
    }
    ListNode* swapPairs(ListNode* head) {
        if (!head)
            return head;
        ListNode* newhead = (head->next) ? head->next:head;
        ListNode* concat = NULL;
        while (head && head->next){
            ListNode* pleft = swap(head, head->next);
            if (concat)
                concat->next->next = pleft;
            if (pleft->next->next)
                head = pleft->next->next;
            concat = pleft;
        }
        return newhead;
    }
};

我们注意到,不同的循环之间,如果没有concat这个过程,其是会断掉的。


容易出错的问题

  1. 在递归版本中,有一个边界容易遗忘,那个就是head && head->next不成立的时候,这个时候,head != NULL但是head->next == NULL,因此需要返回head就足够了。
posted @ 2020-02-05 00:29  FesianXu  阅读(47)  评论(0编辑  收藏  举报