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.
解题思路:
传统的链表操作题,需要注意如果结点不是偶数,最后一个结点不需要交换,放在队尾。
先条件:head不为空;head至少包含两个结点;
后条件:返回指向新链表第一个结点的指针;原链表结点全部加入新链表中,并且偶数对结点两两互换;新旧链表的结点数一致。
不变式:1、新建一个newhead指针,newhead->next永远指向新链表的头部;
2、新建一个newlist指针,newlist永远指向新链表的最后一个结点;
3、newlist->next始终为NULL;
4、head指针永远指向还未被操作的旧链表第一个结点;
5、新链表上的结点数加上旧链表剩余的结点数之和,应该和原链表结点数一致;
当head为空时,循环结束,每次循环:
1、将head中的结点按对取出~交换~插入newlist末端
2、若head只剩一个结点不够一对,则直接插入newlist末端;
解题步骤:
1、新建preHead结点,新建newlist指针;
2、按照不定式分析,开始循环,循环结束标志为head为空:
(1)如果当前head只剩一个结点,则将其插入newlist后,并结束循环;
(2)取出待操作的两个结点,head后移两位;
(3)将这两个结点反转插入newlist中
3、释放preHead,返回newlist;
代码1:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode* swapPairs(ListNode* head) { 12 /* 13 if (head == NULL || head->next == NULL) 14 return head; 15 */ 16 ListNode* newhead = new ListNode(0); 17 ListNode* newlist = newhead; 18 ListNode* preNode = NULL; 19 20 while (head != NULL) { 21 if (head->next == NULL) { 22 newlist->next = head; 23 break; 24 } 25 preNode = head; 26 head = head->next->next; 27 preNode->next->next = preNode; 28 newlist->next = preNode->next; 29 newlist = preNode; 30 newlist->next = NULL; 31 } 32 33 head = newhead->next; 34 delete newhead; 35 return head; 36 } 37 };
代码2,使用二维指针:
基本逻辑实现:
1 ListNode **p = &head; 2 while (*p && (*p)->next) { 3 // n表示待交换的两个结点中,后一个结点 4 ListNode* n = (*p)->next; 5 (*p)->next = n->next; 6 n->next = *p; 7 p = &(*p)->next; 8 }
由于二维指针p一直在操作当前需要交换的结点,不断向后迭代,而head指针此时指向的是链表中第二个结点(前两个交换);
因此上述代码唯一的问题是,没有指针指向头结点,无法返回...
所以我们希望在第一轮交换时,将head结点重新指向交换后的第一个结点。观察到第一轮交换时,*p其实就代表head,操作*p的指向,就是操作head的指向。
所以,最终代码为:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode* swapPairs(ListNode *head) { 12 ListNode **p = &head; 13 14 while (*p && (*p)->next) { 15 ListNode* n = (*p)->next; 16 (*p)->next = n->next; 17 n->next = *p; 18 *p = n; 19 p = &(*p)->next->next; 20 } 21 22 return head; 23 } 24 };