147. Insertion Sort List(对链表进行插入排序)

题目链接:https://leetcode.com/problems/insertion-sort-list/

Sort a linked list using insertion sort.


A graphical example of insertion sort. The partial sorted list (black) initially contains only the first element in the list.
With each iteration one element (red) is removed from the input data and inserted in-place into the sorted list
 

Algorithm of Insertion Sort:

  1. Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list.
  2. At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there.
  3. It repeats until no input elements remain.


Example 1:

Input: 4->2->1->3
Output: 1->2->3->4

思路还是插入排序的比较交换思想,但由于是链表节点,交换节点是必须从头部往后依次比较。

 先看AC 31ms代码,接下来以Example为例慢慢解释:

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

最初创建一个dummy节点,他是每一步比较的起始节点。

     最初情形:dummy->null

                      4->2->1->3->null

1 . cur=4,prev.next=null 所以内层while进不去,接下来节点4的next=null,prev.next=节点4,

    cur指向节点2,prev恢复到dummy。

  这一步完成后,出现 :dummy->4->null

                                      2->1->3->null

2 . cur=2,prev.next=4 不符合内层while条件,接下来,节点2的next指向4,prev.next指向节点2

   cur指向节点1,prev恢复到dummy。

 这一步完成后:

   dummy->2->4->null

   1->3->null

接下来的步骤同理

.......

核心思想就是每次从dummy开始往后遍历,把当前节点cur插入到prev和prev.next之间。

这种思路的不足之处在于,如果一个序列本来就是有序的,prev仍会从dummy开始走到cur。

比如:

4->2->1->5->7->3->8->6->9->.......0->16->null

当cur=9时,前面的都会连接在dummy后面有序,此时没必要让prev从dummy开始再走8步

直接连接到8后面即可,如果cur=  -2,才需要从dummy开始向后确定插入的位置。

AC 3ms 98.5% java:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode insertionSortList(ListNode head) {
        
        ListNode dummy=new ListNode(0);
        ListNode cur=head;
        ListNode prev=dummy;
        ListNode next=null;
        while(cur != null){
            next=cur.next;
            if(prev.next != null && prev.next.val > cur.val)
                prev=dummy;//加了这一个判断
            while(prev.next != null && prev.next.val < cur.val){
                prev=prev.next;
            }
            cur.next=prev.next;
            prev.next=cur;
            
            cur=next;
        }
        return dummy.next;

    }
}

猜你喜欢

转载自blog.csdn.net/God_Mood/article/details/89432052