2019.2.1
题目描述:
Given a linked list, swap every two adjacent nodes and return its head.
Example:
Given1->2->3->4
, you should return the list as2->1->4->3.
Note:
- Your algorithm should use only constant extra space.
- You may not modify the values in the list's nodes, only nodes itself may be changed.
这题是将一个链表相邻的结点两两交换,最后返回结果链表,要求只是用常数级额外空间,并且不能只是单纯的改变节点内部的值,而是需要实际的进行结点交换。
解法一:
这题其实就是考察链表结点的交换。首先我们知道,在链表的算法中,我们都会设置一个头结点,这样可以简化第一个结点的操作,从而统一所有结点的操作。所以我们可以先建立一个dummy结点用来作为头结点。之后就是循环进行结点两两交换的过程了,感觉也没什么多说的,链表最基本的操作,需要注意的就是一定要保证在交换过程中不能断链,所以我们可以设置一个新指针指向后继结点。
最后返回的时候要注意返回dummy->next而不是head,因为head在交换过程中始终指向未交换前的第一个结点,若是最后返回head,会漏掉结束后的第一个结点,而dummy->next始终指向第一个结点。
C++代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummy=new ListNode(-1);
dummy->next=head;
ListNode* pre=dummy,*p=dummy->next,*q;
while(p&&p->next){
q=p->next;
pre->next=q;
p->next=q->next;
q->next=p;
pre=p;
p=p->next;
}
return dummy->next;
}
};
解法二:递归
其实解法一就是一种迭代的算法,这题也可以用递归来解决。利用回溯的思想,不断遍历到末尾结点,先交换最后两个结点再不断跳出递归交换前面的结点即可。
C++代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(!head)return NULL;
if(!head->next)return head;
ListNode* x=head->next;
head->next=swapPairs(x->next) ;
x->next=head;
return x;
}
};