剑指offer:数据流中的中位数,数组中的逆序对
剑指 Offer 41. 数据流中的中位数
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。
利用了大小堆,通过优先队列实现。
代码如下:
class MedianFinder {
Queue<Integer> A,B;
/** initialize your data structure here. */
public MedianFinder() {
A= new PriorityQueue<>(); // 小顶堆,保存较大的一半
B= new PriorityQueue<>((x,y)->(y-x));
}
public void addNum(int num) {
if(A.size()!= B.size()){
A.add(num);
B.add(A.poll());
}
else{
B.add(num);
A.add(B.poll());
}
}
public double findMedian() {
return A.size() != B.size() ? A.peek() : (A.peek () + B.peek() ) /
2.0 ;
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
剑指 Offer 51. 数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
输入: [7,5,6,4]
输出: 5
利用了 归并排序,
class Solution {
int [] nums, temp ;
public int reversePairs(int[] nums) {
this.nums = nums;
temp = new int [nums.length];
return mergeSort(0,nums.length-1);
}
private int mergeSort(int l,int r){
//终止条件
if(l>=r) return 0;
// 递归划分
int mid = (l+r)/2;
int ans = mergeSort(l,mid) + mergeSort(mid+1,r);
// 合并阶段
int i = l , j = mid+1;
for(int k = l;k<=r ;k++){
temp[k] = nums[k];
}
for(int k = l ;k<=r ; k++){
if(i == mid+1){
nums[k]=temp[j++];
}
else if(j== r+1 || temp[i]<= temp[j]){
nums[k] = temp[i++];
}
else{
nums[k] = temp[j++];
ans += mid-i+1;
}
}
return ans;
}
}