给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
- 递归解法
public ListNode swapPairs(ListNode head) {
//递归结束条件:当没有结点或者只有一个结点时,无需交换
if(head==null || head.next==null){
return head;
}
ListNode next = head.next;
//递归调用,需要把head指向next之后已经交换好的链表,即以next.next作为头指针 调用了递归函数的
head.next = swapPairs(next.next);
next.next = head;
//next指向头了
return next;
}
解题思路:
递归需要采用分治的思想,即问题的求解可以划分成多个具有相同解法的子问题的解的合并。本题先将头指针的next指针指向next之后的链表,然后将next的下一个指针再反转指向head。此时next之后的部分链表又可以看出是一个求解
- 非递归解法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
//哑结点,便于返回结果
ListNode dummpy = new ListNode(0);
dummpy.next = head;
ListNode pre = dummpy;
ListNode cur;
ListNode next;
while(head!=null && head.next!=null){
cur = head;
next = head.next;
pre.next=cur.next;
cur.next = next.next;
next.next = cur;
pre=cur;
head = cur.next;
}
return dummpy.next;
}
}
解题思路:
1、此题利用了三个指针pre(前置)、cur(现在)、next(下一个)
2、先将pre.next指向cur的下一个结点,然后将cur.next指向next的下一个 节点,然后将next.next指向cur,这样就完成第一轮的两个结点的交换
3、接下来将head移动到cur.next,pre移动到cur,开启下一轮交换
4、此题非递归的思想不难,但是编写代码的过程中,指针的概念很容易让人
混淆,java中虽然没有指针,但实际上一个对象既是一个引用(指针),
若一个对象被赋予了另一个值,只能说明指针移动了,之前所引用的对象 还是实际存在的,不用太疑惑