题目:
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
链表中节点的数目在范围 [0, 100] 内
0 <= Node.val <= 100
进阶:你能在不修改链表节点值的情况下解决这个问题吗?(也就是说,仅修改节点本身。)
分析:
主要想法是用递归或迭代来解决问题。
- 递归:
使用递归来解决该题,主要就是递归的三部曲:
1.找终止条件:本题终止条件很明显,当递归到链表为空或者链表只剩一个元素的时候,没得交换了,自然就终止了。
2.找返回值:返回给上一层递归的值应该是已经交换完成后的子链表。
3.单次的过程:因为递归是重复做一样的事情,所以从宏观上考虑,只用考虑某一步是怎么完成的。我们假设待交换的俩节点分别为head和next, next 的应该接受上一级返回的子链表(参考第2步)。就相当于是一个含三个节点的链表交换前两个节点,就很简单了。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* swapPairs(struct ListNode* head){
if(head==NULL||head->next==NULL) //头指针为空或只有一个结点
return head; //递归出口
struct ListNode *newnode;
newnode=head->next;
head->next=swapPairs(newnode->next);//返回值是已经交换完的子链表
newnode->next=head;
return newnode;
}
2.迭代:
迭代的思路比较容易想到,但是要注意边界情况。这里我们设置哑结点来方便操作。
struct ListNode* swapPairs(struct ListNode* head){
struct ListNode *temp,*dummy=(struct ListNode*)malloc(sizeof(struct ListNode));
dummy->next=head;
temp=dummy;
while(temp->next!=NULL&&temp->next->next!=NULL){
struct ListNode *node1=temp->next;
struct ListNode *node2=temp->next->next;
temp->next=node1->next;
node1->next=node2->next;
node2->next=node1;
temp=node1;
}
return dummy->next;
}