第一题:剑指 Offer 40. 最小的k个数
问题描述
思路
快排序
代码
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if (k == 0 || arr.length == 0) {
return new int[0];
}
// 最后一个参数表示我们要找的是下标为k-1的数
return quickSearch(arr, 0, arr.length - 1, k - 1);
}
private int[] quickSearch(int[] nums, int lo, int hi, int k) {
// 每快排切分1次,找到排序后下标为j的元素,如果j恰好等于k就返回j以及j左边所有的数;
int j = partition(nums, lo, hi);
if (j == k) {
return Arrays.copyOf(nums, j + 1);
}
// 否则根据下标j与k的大小关系来决定继续切分左段还是右段。
return j > k? quickSearch(nums, lo, j - 1, k): quickSearch(nums, j + 1, hi, k);
}
// 快排切分,返回下标j,使得比nums[j]小的数都在j的左边,比nums[j]大的数都在j的右边。
private int partition(int[] nums, int lo, int hi) {
int v = nums[lo];
int i = lo, j = hi + 1;
while (true) {
while (++i <= hi && nums[i] < v);
while (--j >= lo && nums[j] > v);
if (i >= j) {
break;
}
int t = nums[j];
nums[j] = nums[i];
nums[i] = t;
}
nums[lo] = nums[j];
nums[j] = v;
return j;
}
}
第二题:剑指 Offer 41. 数据流中的中位数
问题描述
思路
代码
class MedianFinder {
PriorityQueue <Integer> left;
PriorityQueue <Integer> right;
/** initialize your data structure here. */
public MedianFinder() {
left = new PriorityQueue<>((n1,n2) -> n2-n1);
right = new PriorityQueue<>();
}
public void addNum(int num) {
left.add(num);
right.add(left.poll());
if(right.size() > left.size()+1) left.add(right.poll());
}
public double findMedian() {
if(right.size() > left.size()) return right.peek();
return (double)(left.peek() + right.peek()) /2;
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/