Insertion Sort List
Sort a linked list using insertion sort.

1.解题思路

题目很简单,就是要求用插入排序的方法来为链表排序。插入排序就是每次遍历一个新的元素,将其插入到前面已经排好序的元素中。
因为头结点没法确定,所以我们用一个dummy节点;然后开始向后逐个遍历,当前遍历的节点为cur,另外sortnode每次都指向已经排好序的第一个节点dummy,然后从dummy开始往后,直到找到sortnode.next.val>=cur.val,则表示cur节点要插到有序链表的sortnode后面。

2.代码

public class Solution {
    public ListNode insertionSortList(ListNode head) {
        if(head==null||head.next==null) return head;
        ListNode dummy=new ListNode(0);
        ListNode cur=head;
        while(cur!=null){
            ListNode sortnode=dummy;
            while(sortnode.next!=null&&sortnode.next.val<cur.val)
                sortnode=sortnode.next;
            ListNode tmp=cur.next;
            cur.next=sortnode.next;
            sortnode.next=cur;
            cur=tmp;
        }
        return dummy.next;
    }
}

Merge Two Sorted Lists
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

1.解题思路

合并两个有序链表,同样需要构造一个Dummy节点。
1)考虑特殊情况,如果有一个链表为空,则直接返回另一个链接;
2)利用两个指针p,q遍历两个链表,如果都不为空,则循环继续;
3)使用node指向新链表的最后一个节点,初始化为dummy
4) 比较p,q的数值的大小,如果p小于q,则把p加到node.next,并且node赋值为p,而p指针需要前进一个;
5) 结束循环时,check一下是否还有链表中有剩余元素,并将剩余元素加入到新链表node指针的后面。

2.代码

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null) return l2;
        if(l2==null) return l1;
        ListNode dummy=new ListNode(0);
        ListNode p=l1;
        ListNode q=l2;
        ListNode node=dummy;
        while(p!=null&&q!=null){
            if(p.val<q.val){
                node.next=p;
                node=p;
                p=p.next;
                
            }
            else {
                node.next=q;
                node=q;
                q=q.next;
            }
        }
        if(p!=null)
            node.next=p;
        if(q!=null)
            node.next=q;
        return dummy.next;
    }
}

Sort List

Sort a linked list in O(n log n) time using constant space complexity.

1.解题思路

题目要求时间复杂度为O(n log n),所以我们就想到用归并排序,自然就想到和上一题的mergeTwoLists。
但要做mergeTwoLists,必须得先将当前的list分割成两个List,所以采用递归实现。
要分割链表,最简单的办法就是找到中点,那很明显是利用slow,fast来实现,最后slow就是链表的中间点。但要注意我们要将Slow的前一个节点记录下来pre,在找到中点后,我们要将pre.next=null,这样链表才能分割成2个。
2.代码

public class Solution {
    public ListNode sortList(ListNode head) {
        if(head==null||head.next==null) return head;
        ListNode slow=head,fast=head,pre=null;
        while(fast!=null&&fast.next!=null){
            pre=slow;
            slow=slow.next;
            fast=fast.next.next;
        }
        pre.next=null;
        ListNode l1=sortList(head);
        ListNode l2=sortList(slow);
        return mergeTwoSortedList(l1,l2);
    }
    private ListNode mergeTwoSortedList(ListNode l1,ListNode l2){
        if(l1==null) return l2;
        if(l2==null) return l1;
        ListNode dummy=new ListNode(0);
        ListNode p=l1;
        ListNode q=l2;
        ListNode node=dummy;
        while(p!=null&&q!=null){
            if(p.val<q.val){
                node.next=p;
                node=p;
                p=p.next;
                
            }
            else {
                node.next=q;
                node=q;
                q=q.next;
            }
        }
        if(p!=null)
            node.next=p;
        if(q!=null)
            node.next=q;
        return dummy.next;
    }
}

tiffanytown
6 声望2 粉丝

keep learning