1. public class MergeSort implements IMutableSorter {
  2. @Override
  3. public void sort(int[] A) {
  4. //左闭右闭
  5. mergeSort(A, 0, A.length - 1);
  6. }
  7. private void mergeSort(int[] A, int left, int right) {
  8. if (left >= right) {
  9. return;
  10. }
  11. int mid = left + (right - left) / 2;
  12. mergeSort(A, left, mid);
  13. mergeSort(A, mid + 1, right);
  14. merge(A, left, mid, right);
  15. }
  16. private void merge(int[] A, int left, int mid, int right) {
  17. int[] L = Arrays.copyOfRange(A, left, mid + 1);
  18. int[] R = Arrays.copyOfRange(A, mid + 1, right + 1);
  19. int i = 0, j = 0;
  20. for (int k = left; k <= right; k++) {
  21. if (i == L.length) {
  22. A[k] = R[j++];
  23. } else if (j == R.length || L[i] <= R[j]) {
  24. A[k] = L[i++];
  25. } else {
  26. A[k] = R[j++];
  27. }
  28. }
  29. }
  30. }

merge其实还有另外一种写法
看看能记住哪种吧

  1. private void merge(int[] A, int left, int mid, int right) {
  2. //预留一个多余的节点
  3. int[] L = Arrays.copyOfRange(A, left, mid + 2);
  4. int[] R = Arrays.copyOfRange(A, mid + 1, right + 2);
  5. L[L.length - 1] = Integer.MAX_VALUE;
  6. R[R.length - 1] = Integer.MAX_VALUE;
  7. int i = 0, j = 0;
  8. for (int k = left; k <= right; k++) {
  9. if (L[i] <= R[j]) {
  10. A[k] = L[i++];
  11. } else {
  12. A[k] = R[j++];
  13. }
  14. }
  15. }

148. 排序链表

可以理解为归并排序
对找到中间节点做了一点修改,这里的函数找到的是中间节点的前一个节点,方便断开链表。

class Solution {
    public ListNode sortList(ListNode head) {
        if(head==null||head.next==null) return head;
        ListNode midNode=findMidNode(head);
        ListNode rightHead=midNode.next;
        midNode.next=null;
        ListNode left=sortList(head);
        ListNode right=sortList(rightHead);
        return mergeTwoLists(left,right);
    }

    private ListNode findMidNode(ListNode head){
        if(head==null||head.next==null) return head;
        ListNode slow=head;
        ListNode fast=head.next.next;
        while(fast!=null&&fast.next!=null){
            slow=slow.next;
            fast=fast.next.next;
        }
        return slow;
    }

    private ListNode mergeTwoLists(ListNode l1,ListNode l2){
        ListNode res=new ListNode();
        ListNode cur=res;
        while(l1!=null&&l2!=null){
            if(l1.val>l2.val){
                cur.next=l2;
                l2=l2.next;
            }else{
                cur.next=l1;
                l1=l1.next;
            }
            cur=cur.next;
        }
        cur.next=l1!=null?l1:l2;
        return res.next;
    }
}


剑指 Offer 51. 数组中的逆序对

class Solution {
    int count=0;

    public int reversePairs(int[] nums) {
        mergeSort(nums,0,nums.length-1);
        return count;
    }

    public void mergeSort(int[] nums, int l, int r){
        if(l>=r){
            return;
        }
        int mid=l+(r-l)/2;
        mergeSort(nums,l,mid);
        mergeSort(nums,mid+1,r);
        merge(nums,l,mid,r);
    }

    public void merge(int[] nums,int l,int mid,int r){
        int[] L=Arrays.copyOfRange(nums,l,mid+1);
        int[] R=Arrays.copyOfRange(nums,mid+1,r+1);
        int i=0,j=0;
        for(int k=l;k<=r;k++){
            if(i==L.length){
                nums[k]=R[j++];
            }else if(j==R.length||L[i]<=R[j]){
                nums[k]=L[i++];
            }else{
                nums[k]=R[j++];
                count+=L.length-i;
            }
        }
    }
}