Leetcode-Swap Nodes in Pairs

作者:disappearedgod

文章出处:http://blog.csdn.net/disappearedgod/article/details/23971481
时间:2014-4-17

题目


Swap Nodes in Pairs

  Total Accepted: 11114  Total Submissions: 35009 My Submissions

Given a linked list, swap every two adjacent nodes and return its head.

For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can

 Definition for singly-linked list.
 public class ListNode {
     int val;
     ListNode next;
     ListNode(int x) {
         val = x;
         next = null;
     }
 }
 


解法

一个错误的想法
奇数偶数解法(可以但是写错)
 private ListNode swapPairs1(ListNode head){
        if(head==null||head.next == null)
        return head;

 
        ListNode retNode =new ListNode(0);
        retNode.next = head;
        ListNode oddNode = head;
        ListNode evenNode = head.next;
        int count =0;
        ListNode node =retNode;
       
        while(oddNode!=null && evenNode!=null){
             ListNode nexth = evenNode.next;
            
            node.next=evenNode;
            evenNode.next=oddNode;
            node = node.next.next;
            
            
            if(nexth!=null&&nexth.next==null){// num of list is odd
                node.next=nexth;
                break;
            }
            if(nexth==null){
                break;
            }
            oddNode = nexth;
            evenNode = nexth.next;
        }
      
        
        return retNode.next;
    }


精妙解法

public class Solution {
    public ListNode swapPairs(ListNode head) {
        return swapPairs2(head);
    }
    private ListNode swapPairs2(ListNode head){
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode p = dummy;
        //(0-p) -(1-h)-2-3-4-5
        while(p.next != null && p.next.next != null){
            ListNode q = p.next.next; //(0-p) -(1-pn)-(2-q)-3-4-5
            p.next.next = q.next;//(0-p) -(1-pn)-(2-q)-(3-pnn)-4-5
            q.next = p.next;//(0-p) -(1-pn-qn)-(2-q)-(3-pnn)-(4-qn)-5
            p.next = q;//(0-p) -(1-qn)-(2-pn)-(3-pnn)-(4-qn)-5
            p = p.next.next;//(0) -(1-qn)-(2-pn)-(3-p)-(4-qn)-5
        }
        return dummy.next;
    }
}

这么看其实还是不太懂,但是如果把测试用例打印出来就不难发现,其实p是用来调配结果的指针,q是用来调换位置的。
这道题需要用一定的空间来解,这题的空间效率大约是O(logn),非常精妙。
用q先存奇数位,p存偶数位,通过互相调换来移动。
测试用例大家也不必写了,做如下分享。
private ListNode swapPairs2(ListNode head){
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode p = dummy;
        //(0-p) -(1-h)-2-3-4-5
        int whilecount = 1;
        int linecount = 0;
        while(p.next != null && p.next.next != null){
        	linecount =0;
            ListNode q = p.next.next; //(0-p) -(1-pn)-(2-q)-3-4-5
            printcode(++linecount,whilecount,"ListNode q = p.next.next;",p,q);//test          
                        
            p.next.next = q.next;//(0-p) -(1-pn)-(2-q)-(3-pnn)-4-5
            printcode(++linecount,whilecount,"p.next.next = q.next;",p,q);//test           
            
            q.next = p.next;//(0-p) -(1-pn-qn)-(2-q)-(3-pnn)-(4-qn)-5
            printcode(++linecount,whilecount,"q.next = p.next;",p,q);//test
                        
            p.next = q;//(0-p) -(1-qn)-(2-pn)-(3-pnn)-(4-qn)-5
            printcode(++linecount,whilecount,"p.next = q;",p,q);//test
                        
            p = p.next.next;//(0) -(1-qn)-(2-pn)-(3-p)-(4-qn)-5
            printcode(++linecount,whilecount,"p = p.next.next;",p,q);//test
            
            System.out.println("------------------------------------------------------");
            whilecount++;
        }
        return dummy.next;
    }

private void printcode(int linecount,int count,String string,ListNode p, ListNode q) {
		// TODO Auto-generated method stub
		System.out.println("Line "+linecount+" Count"+count+":"+"code=="+string);
        System.out.println("q:"+q.val);
        testList.write(q);
        System.out.println("p:"+p.val);
        testList.write(p);
		
	}



public class testList {
	protected static void write(ListNode head){
		for(;head.next!=null;head=head.next)
			System.out.print(head.val+"->");
		System.out.println(head.val);
	}

}

 
 

测试结果:

0->1->2->3->4->5->6->7->8
Line 1 Count1:code==ListNode q = p.next.next;
q:1
1->2->3->4->5->6->7->8
p:-1
-1->0->1->2->3->4->5->6->7->8
Line 2 Count1:code==p.next.next = q.next
q:1
1->2->3->4->5->6->7->8
p:-1
-1->0->2->3->4->5->6->7->8
Line 3 Count1:code==q.next = p.next;
q:1
1->0->2->3->4->5->6->7->8
p:-1
-1->0->2->3->4->5->6->7->8
Line 4 Count1:code==p.next = q;
q:1
1->0->2->3->4->5->6->7->8
p:-1
-1->1->0->2->3->4->5->6->7->8
Line 5 Count1:code==p = p.next.next;
q:1
1->0->2->3->4->5->6->7->8
p:0
0->2->3->4->5->6->7->8
------------------------------------------------------
Line 1 Count2:code==ListNode q = p.next.next;
q:3
3->4->5->6->7->8
p:0
0->2->3->4->5->6->7->8
Line 2 Count2:code==p.next.next = q.next
q:3
3->4->5->6->7->8
p:0
0->2->4->5->6->7->8
Line 3 Count2:code==q.next = p.next;
q:3
3->2->4->5->6->7->8
p:0
0->2->4->5->6->7->8
Line 4 Count2:code==p.next = q;
q:3
3->2->4->5->6->7->8
p:0
0->3->2->4->5->6->7->8
Line 5 Count2:code==p = p.next.next;
q:3
3->2->4->5->6->7->8
p:2
2->4->5->6->7->8
------------------------------------------------------
Line 1 Count3:code==ListNode q = p.next.next;
q:5
5->6->7->8
p:2
2->4->5->6->7->8
Line 2 Count3:code==p.next.next = q.next
q:5
5->6->7->8
p:2
2->4->6->7->8
Line 3 Count3:code==q.next = p.next;
q:5
5->4->6->7->8
p:2
2->4->6->7->8
Line 4 Count3:code==p.next = q;
q:5
5->4->6->7->8
p:2
2->5->4->6->7->8
Line 5 Count3:code==p = p.next.next;
q:5
5->4->6->7->8
p:4
4->6->7->8
------------------------------------------------------
Line 1 Count4:code==ListNode q = p.next.next;
q:7
7->8
p:4
4->6->7->8
Line 2 Count4:code==p.next.next = q.next
q:7
7->8
p:4
4->6->8
Line 3 Count4:code==q.next = p.next;
q:7
7->6->8
p:4
4->6->8
Line 4 Count4:code==p.next = q;
q:7
7->6->8
p:4
4->7->6->8
Line 5 Count4:code==p = p.next.next;
q:7
7->6->8
p:6
6->8

------------------------------------------------------



返回


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值