文章目录
- 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;
}