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; } }