[LC]346. Moving Average from Data Stream

一、问题描述

Given a stream of integers and a window size, calculate the moving average of all integers in the sliding window.

For example,

MovingAverage m = new MovingAverage(3);
m.next(1) = 1
m.next(10) = (1 + 10) / 2
m.next(3) = (1 + 10 + 3) / 3
m.next(5) = (10 + 3 + 5) / 3

二、我的思路

数据结构:用一个int size存window大小,用一个ArrayList存数据流。

算法:当数据流长度小于window大小时,有多少加多少;当数据流大于window大小时,以window大小为限制。

class MovingAverage {

    /** Initialize your data structure here. */
    private int size = 0;
    private ArrayList<Integer> list = new ArrayList<Integer>();
    
    public MovingAverage(int size) {
        this.size = size;
    }
    
    public double next(int val) {
        if(this.size == 0){
            return 0;
        }
        
        this.list.add(val);
        double sum = 0;
        for(int i = this.list.size()-1; i >= Math.max(0, this.list.size()-this.size); i --){
            sum += this.list.get(i);
        }

        return sum/Math.min(this.size, this.list.size());
    }
}

/**
 * Your MovingAverage object will be instantiated and called as such:
 * MovingAverage obj = new MovingAverage(size);
 * double param_1 = obj.next(val);
 */


三、淫奇技巧

看了discuss以后,发现即使这么简单的题目,还是很能看出差距的!!

1)

public class MovingAverage {
    private int [] window;
    private int n, insert;
    private long sum;
    
    /** Initialize your data structure here. */
    public MovingAverage(int size) {
        window = new int[size];
        insert = 0;
        sum = 0;
    }
    
    public double next(int val) {
        if (n < window.length)  n++;
        sum -= window[insert];
        sum += val;
        window[insert] = val;
        insert = (insert + 1) % window.length;
        
        return (double)sum / n;
    }
}
O(1)的方法。超级巧妙

用了一个数组作为window;n记录分母,insert记录数据流长度。通过把insert对windowSize求余得到要替换出局的数字和新数字存放的位置!!

2) 依然O(1)

public class MovingAverage {
private double previousSum = 0.0;
private int maxSize;
private Queue<Integer> currentWindow;

public MovingAverage(int size) {
    currentWindow = new LinkedList<Integer>();
    maxSize = size;
}

public double next(int val) {
    if (currentWindow.size() == maxSize)
    {
        previousSum -= currentWindow.remove();
    }
    
    previousSum += val;
    currentWindow.add(val);
    return previousSum / currentWindow.size();
}}
巧妙的用了Queue这种数据结构维护window里的数据,同时也用了一个变量记录sum,非常简洁!

四、知识点

Queue<Integer> queue = new LinkedList<Integer>();
另外还有余数的神奇作用~


五、碎碎念

虽然题目简单,但是仍然能看出差距好大啊啊啊!!

谷歌电面在即,继续加油!每天都要比昨天的自己好一点~

It‘s time to test how bad I want it!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值