剑指 Offer 41. 数据流中的中位数 - 力扣(LeetCode)
法一
这个方法就是直接暴力用集合跑
class MedianFinder {
List<Integer> list = new ArrayList<>();
/** initialize your data structure here. */
public MedianFinder() {
}
public void addNum(int num) {
list.add(num);
}
public double findMedian() {
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
if (list.size() == 1)
return list.get(0);
if (list.size()%2 == 1)
return list.get(list.size()/2);
else
return (list.get(list.size()/2) + list.get(list.size()/2 - 1))/2D;
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
法二
采用一个链表存储这些数字,用一个指针mid一直指向中位数(如果为偶数指向第一个数),再采用一个标志flag来表示当前数组是偶数还是奇数,奇数为1,偶数为0。
一个数进入时通过链表选择合适地点进入
如果进入点大于中位数,则mid右移,如果进入点小于等于中位数,则mid左移,并同步更新flag
public class MedianFinder {
/*
采用一个链表存储这些数字,用一个指针mid一直指向中位数(如果为偶数指向第一个数),再采用一个标志flag来表示当前数组是偶数还是奇数,奇数为1,偶数为0。
一个数进入时通过链表选择合适地点进入
如果进入点大于等于中位数,则mid右移,如果进入点小于中位数,则mid左移,并同步更新flag
*/
/** initialize your data structure here. */
//创建链表
static class Node {
public int val;
public Node left;
public Node right;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val,Node _left,Node _right) {
val = _val;
left = _left;
right = _right;
}
};
Node head = null;
//创建中位数指针
Node mid;
//创建标志位
int flag;
public MedianFinder() {
}
public void addNum(int num) {
//先new出一个节点来装num
Node node = new Node(num);
//寻找到合适地点
Node s = head;
//只有一个节点就进入,并且初始化
if (head == null){
head = node;
mid = node;
flag = 1;
return;
}
while (s.right!=null&&num>=s.val){
s = s.right;
}
//找到改嵌入的位置
if (s.right == null&&num >= s.val){
node.left = s;
s.right = node;
}else {
node.left = s.left;
node.right = s;
if (s.left != null){
s.left.right = node;
}else{
head = node;
}
s.left = node;
}
if (num >= s.val){
}else {
}
//开始修改mid指针与flag
if (num >= mid.val){
if (flag == 0){
//为偶数
flag++;
mid = mid.right;
}else {
//为奇数
flag = (flag+1)%2;
}
}else {
if (flag == 0){
flag++;
}else {
flag = (flag+1)%2;
mid = mid.left;
}
}
}
public double findMedian() {
if (flag == 1){
return mid.val;
}else {
return (mid.val+mid.right.val)/2.D;
}
}
}
这个里面的判断太过于复杂,所以不建议用提升只有一点