[英]Optimizing solution for space and time
最近,一位比我年長的開發人員給了我一個看似很小的 JavaScript 編程挑戰。
它類似於:
編寫代碼以在將新數字插入跟蹤器 class 時持續跟蹤最高、最低和平均溫度。
使用以下方法編寫 class TempTracker:
- 一種插入新溫度的方法。
- 一種獲得迄今為止我們見過的最高溫度的方法
- 一種獲得迄今為止我們見過的最低溫度的方法
- 一種獲取迄今為止我們看到的所有溫度平均值的方法
優化空間和時間。
下面是我的解決方案(您可以在此處找到包括測試在內的完整源代碼)。
class TempTracker {
constructor() {
this.temperatures = [];
}
all() {
return [...this.temperatures];
}
clear() {
this.temperatures.length = 0;
}
count() {
return this.temperatures.length;
}
insert(temperature) {
if (typeof temperature !== 'number' || Number.isNaN(temperature)) {
throw new TypeError('must be a number');
}
this.temperatures.push(temperature);
}
add(temperature) {
this.insert(temperature);
}
get length() {
return this.count();
}
get lowest() {
return this.check((temperatures) => Math.min(...temperatures));
}
get highest() {
return this.check((temperatures) => Math.max(...temperatures));
}
get average() {
return this.check((temperatures, length) => {
const totalTemperature = temperatures.reduce(
(acc, temperature) => acc + temperature,
// eslint-disable-next-line
0
);
return Number((totalTemperature / length).toFixed(2));
});
}
// should be private method
check(callback) {
if (typeof callback !== 'function') {
throw new TypeError('callback must be a function');
}
if (this.length === 0) {
throw new Error('add at least one temperature value');
}
return callback(this.temperatures, this.length);
}
}
雖然代碼確實按預期工作,但我被告知我的代碼沒有針對空間和時間進行優化,因為隨着輸入增長到數百萬或數十億溫度,用於處理的 memory 將耗盡,並且還提到了其他一些東西,它需要線性時間 O()。
我對數據結構和算法的了解充其量是非常模糊的,我真的在努力改進這方面的知識。
當我問我可以做些什么來改進代碼時,我被告知要使用數組以外的東西來存儲溫度列表,然后讓我思考哪個對這個用例最有意義。
在 JavaScript 中可用的數據結構(至少我知道)中,我能想到的只有Sets和Float32Arrays 。
我能否獲得關於哪個更好以及為什么更好的指導,以及如何改進我的解決方案以“優化空間和時間” ?
您不需要任何復雜的數據結構來完成此任務,您只需要跟蹤:
這需要 O(1) 空間,並且每個所述操作都需要 O(1) 時間(要獲得平均值,將溫度總和除以溫度數)。
對於給定的要求,您實際上並不需要存儲所有單獨的溫度……不需要使用all
方法。
您實際上只需要維護最小值、最大值、總和和計數。 使用這 4 個數字,您可以做所有需要的事情:
class TempTracker {
constructor() {
this._low = Infinity;
this._high = -Infinity;
this._count = 0;
this._sum = 0;
}
insert(temperature) {
if (typeof temperature !== 'number' || Number.isNaN(temperature)) {
throw new TypeError('must be a number');
}
this._low = Math.min(temperature, this._low);
this._high = Math.max(temperature, this._high);
this._count++;
this._sum += temperature;
}
get lowest() {
if (!this._count) throw new Error("no data");
return this._low;
}
get highest() {
if (!this._count) throw new Error("no data");
return this._high;
}
get average() {
if (!this._count) throw new Error("no data");
return Math.round(this._sum * 100 / this._count) / 100;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.