天天看点

LeetCode刷题笔记——排序(插入排序、归并排序、桶排序)1. 插入排序(链表)2. 归并排序(链表)

1. 插入排序(链表)

来源:147题

使用插入排序的方法对链表进行排序,其时间复杂度是 O ( n 2 ) O(n^2) O(n2), n n n是链表的长度:

class Solution {
    public ListNode insertionSortList(ListNode head) {
        if (head == null) {
            return head;
        }
        //创建哑节点 dummyHead
        //引入哑节点是为了便于在 head 节点之前插入节点。
        
        ListNode dummyHead = new ListNode(0);
        dummyHead.next = head;
		//维护 lastSorted 为链表的已排序部分的最后一个节点
		//维护 curr 为待插入的元素
		//
        ListNode lastSorted = head, curr = head.next;
        while (curr != null) {
            if (lastSorted.val <= curr.val) {
                lastSorted = lastSorted.next;
            } else {
                ListNode prev = dummyHead;
                while (prev.next.val <= curr.val) {
                    prev = prev.next;
                }
                lastSorted.next = curr.next;
                curr.next = prev.next;
                prev.next = curr;
            }
            curr = lastSorted.next;
        }
        return dummyHead.next;
    }
}
           

2. 归并排序(链表)

来源:147题

时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的排序算法:归并排序、堆排序和快速排序(快速排序的最差时间复杂度是 O ( n 2 ) O(n^2) O(n2)):

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode sortList(ListNode head) {
        return sort(head,null);
    }

    public ListNode sort(ListNode head, ListNode tail){
    	//递归的终止条件是链表的节点个数小于或等于 11
    	//即当链表为空或者链表只包含 11 个节点时,不需要对链表进行拆分和排序
        if(head==null)return head;
        if(head.next == tail){
            head.next = null;
            return head;
        }
		//寻找链表的中点可以使用快慢指针的做法:快指针每次移动 2 步,慢指针每次移动 1 步
		//当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点。
        ListNode slow = head, fast = head;
        while(fast!=tail){
            slow = slow.next;
            fast = fast.next;
            if(fast!=tail) fast = fast.next;
        }
        ListNode mid = slow;
        ListNode list1 = sort(head, mid);
        ListNode list2 = sort(mid, tail);
        ListNode merge = merge(list1, list2);

        return merge;
    }

    public ListNode merge(ListNode head1, ListNode head2){
        ListNode dummyNode = new ListNode(0);
        ListNode tmp = dummyNode, tmp1 = head1, tmp2 = head2;

        while(tmp1!=null && tmp2!=null){
            if(tmp1.val<=tmp2.val){
                tmp.next = tmp1;
                tmp1 = tmp1.next;
            }else{
                tmp.next = tmp2;
                tmp2 = tmp2.next;
            }
            tmp = tmp.next;
        }
        if(tmp1!=null){
            tmp.next = tmp1;
        }else if(tmp2!=null){
            tmp.next = tmp2;
        }
        return dummyNode.next;
    }
}
           

继续阅读