题目:
链接: https://leetcode.com/problems/insertion-sort-list/
6/12/2017
46ms, 17%
从head开始遍历,碰到相同或者大的就插入,更新next指针
注意
1. 需要用sortedLength来区分已经排好序的部分,或许不用?
2. 设一个dummy node这样prev部分比较好解决
3. 排好序的部分最后一个元素next = null,这样才能在插入之后不形成环
4. 第27行判断是否刚加入的node是排序部分最大的,是的话将其next = null
5. 外循环时每次先保存next,不然内循环会被覆盖。第14行
1 public class Solution { 2 public ListNode insertionSortList(ListNode head) { 3 if (head == null || head.next == null) { 4 return head; 5 } 6 int sortedLength = 1; 7 ListNode cur = head.next; 8 ListNode next; 9 ListNode dummy = new ListNode(-1); 10 dummy.next = head; 11 head.next = null; 12 13 while (cur != null) { 14 next = cur.next; 15 ListNode prev = dummy, sorted = dummy.next; 16 int i = 0; 17 for (; i < sortedLength; i++) { 18 if (sorted.val >= cur.val) { 19 prev.next = cur; 20 cur.next = sorted; 21 break; 22 } else { 23 prev = sorted; 24 sorted = sorted.next; 25 } 26 } 27 if (i == sortedLength) { 28 prev.next = cur; 29 cur.next = null; 30 } 31 sortedLength++; 32 cur = next; 33 } 34 return dummy.next; 35 } 36 }
别人的算法精炼很多,看来sortedLength不需要。做法类似于reverse linkedlist, dummy.next最开始是null,所以之前第3点可以保证。而且可以把所有插入的case统一到一种形式,比我的break和i == sortedLength要好很多
1 public ListNode insertionSortList(ListNode head) { 2 if( head == null ){ 3 return head; 4 } 5 6 ListNode helper = new ListNode(0); //new starter of the sorted list 7 ListNode cur = head; //the node will be inserted 8 ListNode pre = helper; //insert node between pre and pre.next 9 ListNode next = null; //the next node will be inserted 10 //not the end of input list 11 while( cur != null ){ 12 next = cur.next; 13 //find the right place to insert 14 while( pre.next != null && pre.next.val < cur.val ){ 15 pre = pre.next; 16 } 17 //insert between pre and pre.next 18 cur.next = pre.next; 19 pre.next = cur; 20 pre = helper; 21 cur = next; 22 } 23 24 return helper.next; 25 }
更多讨论
https://discuss.leetcode.com/category/155/insertion-sort-list