两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
说明:
1. 你的算法只能使用常数的额外空间。
2. 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
/*
思路:奇数节点标记为before,偶数节点标记为after,当奇数节点大于1时就交换before和after标记的前两个节点的位置
第一次交换最开始的两个结点,只需要考虑和后面节点的关联
第一次之后交换节点就需要考虑和前一个节点的关联,而交换的两个节点的前一个节点就是一次交换节点的最后一个节点,所以在
每次交换节点后都用beforeBefore记录交换的一对节点的第二个节点
*/
//如果没有节点或者只有一个节点,直接返回
if(head==null || head.next==null)
{
return head;
}
//如果只有两个节点直接交换
if(head.next.next==null)
{
ListNode twoNode=head.next;
ListNode oneNode=head;
twoNode.next=oneNode;
oneNode.next=null;
return twoNode;
}
int num1=1;
ListNode before=null;
ListNode after=null;
ListNode current=null;
ListNode beforeBefore=null;
current=head;
while (current!=null)
{
//最后一个节点时
if (current.next==null)
{
//如果是偶数,直接和before交换
if (num1%2==0)
{
after.next.next=current;
current.next=before;
before.next=null;
break;
}
//如果是奇数,还是交换前两个数
else {
before.next=current;
after.next=before;
if (beforeBefore!=null)
{
beforeBefore.next=after;
}
}
}else {
//奇数
if (num1%2==1)
{
//不是第一个
if (num1!=1)
{
before.next=current;
after.next=before;
if (beforeBefore!=null)
{
beforeBefore.next=after;
}
beforeBefore=before;
}
before=current;
}
//偶数
else {
//第二个节点是新链表的第一个节点
if (num1==2)
{
head=current;
}
after=current;
}
num1++;
}
current=current.next;
}
return head;
}
}