文章目录
- 12.1 计数排序
- 面试题75:数组相对排序
 
- 12.2 快速排序
- 面试题76:数组中第k大的数
 
- 12.3 归并排序
- 面试题77:链表排序
- 面试题78:合并排序链表
 
 
12.1 计数排序
面试题75:数组相对排序
题目:
给定两个数组,arr1 和 arr2,
arr2 中的元素各不相同
arr2 中的每个元素都出现在 arr1 中
对 arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。1 <= arr1.length, arr2.length <= 1000
0 <= arr1[i], arr2[i] <= 1000
arr2 中的元素 arr2[i] 各不相同
arr2 中的每个元素 arr2[i] 都出现在 arr1 中
public int[] relativeSortArray(int[] arr1, int[] arr2){
    int[] counts = new int[1001];
    for (int num : arr1) {
        counts[num]++;
    }
    int i = 0;
    for (int num : arr2) {
        while(counts[num] > 0){
            arr1[i++] = num;
            counts[num]--;
        }
    }
    for (int j = 0; j < counts.length; j++) {
        while(counts[j] > 0){
            arr1[i++]  = j;
            counts[j]--;
        }
    }
    return arr1;
}
12.2 快速排序
面试题76:数组中第k大的数
题目:
给定整数数组
nums和整数k,请返回数组中第**k**个最大的元素。请注意,你需要找的是数组排序后的第
k个最大的元素,而不是第k个不同的元素。
public int findKthLargest(int[] nums, int k){
    int target = nums.length - k;
    int start = 0;
    int end = nums.length - 1;
    int index = partition(nums, start, end);
    while(index != target){
        if(index < target){
            start = index + 1;
        } else {
            end = index - 1;
        }
        index = partition(nums, start, end);
    }
    return nums[index];
}
public int partition(int[] array, int start, int end){
    int random =  new Random().nextInt(end - start + 1) + start;
    swap(array, random, end);
    int back = start - 1;
    while(start <= end){
        if(array[start] <= array[end]){
            back++;
            swap(array, back, start);
        }
        start++;
    }
    return back;
}
private static void swap(int[] array, int index1, int index2) {
    int temp = array[index1];
    array[index1] = array[index2];
    array[index2] = temp;
}
12.3 归并排序
面试题77:链表排序
题目:给定链表的头结点
head,请将其按 升序 排列并返回 排序后的链表 。示例:
public ListNode sortList(ListNode head){
    if(head == null || head.next == null){
        return head;
    }
    ListNode head1 = head;
    ListNode head2 = split(head);
    head1 = sortList(head1);
    head2 = sortList(head2);
    return merge(head1, head2);
}
private ListNode split(ListNode head) {
    ListNode fast = head;
    ListNode slow = head;
    while(fast != null && fast.next != null){
        fast = fast.next.next;
        slow = slow.next;
    }
    ListNode second = slow.next;
    slow.next = null;
    return second;
}
private ListNode merge(ListNode head1, ListNode head2) {
    ListNode dummy = new ListNode(-1);
    ListNode cur = dummy;
    while(head1 != null || head2 != null){
        if(head2 == null || (head1 != null && head1.val <= head2.val)){
            cur.next = head1;
            head1 = head1.next;
        } else {
            cur.next = head2;
            head2 = head2.next;
        }
        cur = cur.next;
    }
    return dummy.next;
}
面试题78:合并排序链表
题目:给定一个链表数组,每个链表都已经按升序排列。
请将所有链表合并到一个升序链表中,返回合并后的链表。
/**
 * 小顶堆
 * @param lists
 * @return
 */
public ListNode mergeKLists(ListNode[] lists){
    PriorityQueue<ListNode> heap = new PriorityQueue<>((n1, n2) -> n1.val - n2.val);
    for (ListNode list : lists) {
        if(list != null){
            heap.offer(list);
        }
    }
    ListNode dummy = new ListNode(-1);
    ListNode cur = dummy;
    while(!heap.isEmpty()){
        ListNode node = heap.poll();
        cur.next = node;
        cur = cur.next;
        if(node.next != null){
            heap.offer(node.next);
        }
    }
    return dummy.next;
}
/**
 * 归并排序
 * @param lists
 * @return
 */
public ListNode mergeKListsPro(ListNode[] lists){
    return mergeLists(lists, 0, lists.length - 1);
}
private ListNode mergeLists(ListNode[] lists, int start, int end) {
    if(lists.length == 0) {
        return null;
    }
    if(start == end){
        return lists[start];
    }
    int mid = (start + end) / 2;
    ListNode head1 = mergeLists(lists, start, mid);
    ListNode head2 = mergeLists(lists, mid + 1, end);
    return merge(head1, head2);
}
private ListNode merge(ListNode head1, ListNode head2) {
    ListNode dummy = new ListNode(-1);
    ListNode cur = dummy;
    while(head1 != null || head2 != null){
        if(head2 == null || (head1 != null && head1.val <= head2.val)){
            cur.next = head1;
            head1 = head1.next;
        } else {
            cur.next = head2;
            head2 = head2.next;
        }
        cur = cur.next;
    }
    return dummy.next;
}




















