题意:给一个链表,交换所有相邻的两个结点(在恒定的空间内)
初步分析:
一对一对的处理.再细细一想,这道题太有意思了,因为很有逻辑,我们来慢慢画图,慢慢思索。
前提设定 :每个相邻的块: a -> b
1 我们的循环中要描述的点:要交换的a,要交换的b ab前面那一个。 链表的实质其实就是一个个结点,而结点的实质就是前后两条线,把握一个关键,前面的可以描述后面的(因为有next属性嘛),反之不行(所以往往要先处理后面的,往往对前面的有留存)。
2 核心的操作:ab互换:就是把b连到a,a连到b后面那一个。对链表操作熟悉的人,一下就能知道,肯定是先把a连到b的后面的那个,因为b如果先连到了a,b后面的结点就找不到了!
a.next = b.next;
b.next = a;
3.把a b 向下一个块移动
b = a.next.next;
a = a.next;
4.把原来的b连到新的b上(这个好好画图思考)
pre = a;
pre.next = b;
5.循环异常情况判断:只有一个,一个都没有了
if(a.next==null) //一个都没有了
break;
if(b!= null) //只有一个
pre.next = b;
6.开始异常情况处理:第一个单元就为空(head or head.next为空)
if(head==null || head.next==null)
return head;
最后代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode swapPairs(ListNode head) {
if(head==null || head.next==null)
return head;
ListNode a=head;
ListNode b=head.next;
ListNode pre = null;
ListNode newhead = head.next;
while(a!=null && b!=null){
a.next = b.next;
b.next = a;
if(a.next==null) //后面一个都没有了,那么就不把a b 往后移动了
break;
pre = a;
b = a.next.next;
a = a.next;
if(b!= null) //后面只有一个凑不成一对了,那么就不要改线了(这样少掉最后一个,直接连到空)
pre.next = b; //pre的意义在于交换之后先把先连到下一个单元的后面那个上面,下一次循环只需要交换下一个单元就好,前面在这一次 //就已经处理好了(后面已经没有一个单元例外)
}
return newhead;
}
}