Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

https://leetcode.com/problems/insertion-sort-list/

Sort a linked list using insertion sort.

解题思路:

先回忆一下插入排序。对于num[i],将他插入到前面已经排好序的0...i-1的合适的位置。i从0-n遍历。

这题对于链表操作的难度在于取得当前节点和插入处的前趋节点,因为链表只有next。所以只能取travserse和insert的前一个节点往后遍历。这里还用了一个dummy,接在head前面,因为head可能随时发生变化。最终只要返回dumm.next即可。

这里最容易错的地方就是最后注释,如果traverseNode.next已经被搬到前面去了,其实traverseNode就不要再往后了,因为此时traverseNode.next已经是之前的下一个节点了。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode insertionSortList(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        //traverseNode.next是真正的当前遍历节点,插入在insertNode后面
        ListNode traverseNode = head;
        
        while(traverseNode != null && traverseNode.next != null){
            ListNode insertNode = dummy;
            boolean isSwap = false;
            while(insertNode != traverseNode.next){
                if(insertNode.next.val > traverseNode.next.val){
                    isSwap = true;
                    ListNode tempNode = traverseNode.next;
                    traverseNode.next = tempNode.next;
                    tempNode.next = insertNode.next;
                    insertNode.next = tempNode;
                    break;
                }
                insertNode = insertNode.next;
            }
            //如果traverseNode.next插入到前面去了,traverseNode就不用往后了
            //比如3-2-1,2到前面去了,原来3.next=2,现在3.next=1,其实已经相当于往后一个了
            if(!isSwap){
                traverseNode = traverseNode.next;
            }
        }
        return dummy.next;
    }
}

后来在网上看到另一种方法,http://blog.csdn.net/linhuanmars/article/details/21144553,代码反而更简单。

上面我的方法是类似于一个in-place的方法,它不另外构造一个list的结构,而是在原来的list里调换各个node的顺序。下面的方法是,索性从dummy开始,重新组成一个list,所以这里dummy没有接在head后面。但实际上,由于链表的特点,即使不是in-place的,也不需要占新的内存。

代码比上面我的方法清晰很多。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode insertionSortList(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        
        ListNode dummy = new ListNode(0);
        // dummy.next = head;
        
        ListNode cur = head;
        while(cur != null){
            ListNode pre = dummy;
            while(pre.next != null && pre.next.val <= cur.val){
                pre = pre.next;
            }
            ListNode next = cur.next;
            cur.next = pre.next;
            pre.next = cur;
            cur = next;
        }
        return dummy.next;
    }
}

 

posted on 2015-03-23 16:51  NickyYe  阅读(192)  评论(0编辑  收藏  举报