Leetcode148排序链表

159 阅读1分钟

时间复杂度 O(n log n) 的排序算法有归并排序,快速排序,和桶排序。第一个归并排序应用到分治的思想,比较常考,下面写出列表形式和链表形式的归并排序。

image.png

  • 数组形式的归并排序
public class MergeSort {

    public static void merge(int[] a, int low, int mid, int high) {
        int[] temp = new int[high - low + 1];
        int i = low;// 左指针
        int j = mid + 1;// 右指针
        int k = 0;
        // 把较小的数先移到新数组中
        while (i <= mid && j <= high) {
            if (a[i] < a[j]) {
                temp[k++] = a[i++];
            } else {
                temp[k++] = a[j++];
            }
        }
        // 把左边剩余的数移入数组
        while (i <= mid) {
            temp[k++] = a[i++];
        }
        // 把右边边剩余的数移入数组
        while (j <= high) {
            temp[k++] = a[j++];
        }
        // 把新数组中的数覆盖nums数组
        for (int k2 = 0; k2 < temp.length; k2++) {
            a[k2 + low] = temp[k2];
        }
    }

    public static void mergeSort(int[] a, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            // 左边
            mergeSort(a, low, mid);
            // 右边
            mergeSort(a, mid + 1, high);
            // 左右归并
            merge(a, low, mid, high);
        }
    }
}
  • 链表形式归并排序
class Solution {
    public ListNode sortList(ListNode head) {
        //递归终止条件,凡事用到递归必须有终止条件,否则必定StackOverflow
        if(head==null || head.next==null) return head;
        ListNode slow = head,fast = head.next;
        //此处的快慢指针是为了二分链表,进行归并,等同于int mid = (left+right)/2
        while(fast!=null && fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode midStart = slow.next;
        slow.next = null;
        ListNode left = sortList(head);
        ListNode right = sortList(midStart);
        ListNode h = new ListNode(0);
        ListNode dummy = h;
        while(left!=null && right!=null){
            if(left.val<right.val){
                h.next = left;
                left = left.next;
            }else{
                h.next = right;
                right = right.next;
            }
            h = h.next;
        }
        //链表结构的优势,省去了while循环了
        h.next=left!=null?left:right;
        return dummy.next;
    }
}