[LeetCode]Insertion Sort List
原创
©著作权归作者所有:来自51CTO博客作者byamao1的原创作品,请联系作者获取转载授权,否则将追究法律责任
Question
本题难度Medium。有2种算法分别是: 递归法(省时不省空间)和迭代法(省空间不省时间)
1、递归法
【复杂度】
时间 O(N) 空间 O(N) 函数栈深度
【思路】
由于链表只能向后走,因此将较大值往后插入。先对子链表head.next
进行排序,然后再将head插入到合适的位置,递归进行。
【代码】
public class Solution {
public ListNode insertionSortList(ListNode head) {
//base case
if(head==null)return head;
//require
head.next=insertionSortList(head.next);
ListNode cur=head,tmp=head.next;
while(cur.next!=null&&head.val>cur.next.val){
cur=cur.next;
}
if(cur!=head){
head.next=cur.next;
cur.next=head;
return tmp;
}else
return head;
}
}
2、迭代法
【复杂度】
时间 O(N) 空间 O(1)
【思路】
与方法1相反,将小的节点往前插入。以dummy
作为已排序的链表头。每次从待排序链表中取出一个节点,然后在dummy
链表中从头开始进行比较看插到哪里。
方法2虽然节省空间,但是并省时。真实的插入排序并不是从头开始进行比较,这里是因为链表限制(单向),所以不得已每次从头开始比较。而方法1才是真正符合插入排序精髓的方法(虽然它不省空间)。
【注意】
第4行的代码必须要注释掉,否则就不能将已排序链表和待排序链表区分开。
【代码】
public class Solution {
public ListNode insertionSortList(ListNode head) {
ListNode dummy= new ListNode(Integer.MIN_VALUE);
//dummy.next = head;
for (ListNode cur = head; cur != null;) {
ListNode pos = findInsertPos(dummy, cur.val);
ListNode tmp = cur.next;
cur.next = pos.next;
pos.next = cur;
cur = tmp;
}
return dummy.next;
}
private ListNode findInsertPos(ListNode head, int x) {
ListNode pre = null;
for (ListNode cur = head; cur != null && cur.val <= x; ){
pre = cur; cur = cur.next;
}
return pre;
}
}