假设您有一个对象,例如:
let objToCheck = {
a: 2,
b: 5,
c: 9,
d: 33,
e: 4,
f: 8,
g: 3,
h: 10
};
你将如何以升序返回三个最大值的键,在这种情况下,它将是:[ 'c', 'h', 'd' ]
,在线性时间内?显然你需要遍历整个对象一次来比较所有的值,但是我遇到了一个麻烦的解决方案,它不涉及嵌套循环,我认为是O(n²)。以下是我目前的解决方案:
function findBig3(obj){
const res = [];
const largest = Object.values(obj).sort((a,b) => {return b-a}).slice(0,3);
for (let key in obj){
largest.forEach( (val) => {
if (obj[key] === val) res.push(key);
});
}
return res;
}
我认为您需要声明三个变量,例如big1
,big2
,big3
,并且在循环对象时执行某种类型的比较检查并根据需要重新分配,但我正在努力实施。
答案 0 :(得分:2)
你可以继续推动数组中的3个对象并继续对数组进行排序,假设你需要的元素数量k足够小于n,这可以平均提供线性效率。
let objToCheck = {
a: 2,
b: 5,
c: 9,
d: 33,
e: 4,
f: 8,
g: 3,
h: 10
};
function findBig3(obj){
var res = [-1,-1,-1];
for (let key in obj){
res[3] = obj[key];
res.sort(function(a,b){return b-a});
}
res.pop();
return res;
}
console.log(findBig3(objToCheck));
答案 1 :(得分:1)
该算法在O(n)中运行。
function getThreeLargestKeys(obj){
var k1, k2, k3;
var v1, v2, v3;
v1 = v2 = v3 = -Infinity;
// O(1)
var insertKey = function(key){
var value = obj[key]; // note 1
// note 2
if(value >= v1){
v3 = v2; v2 = v1; v1 = value;
k3 = k2; k2 = k1; k1 = key;
}else if(value >= v2){
v3 = v2; v2 = value;
k3 = k2; k2 = key;
}else if(value >= v3){
v3 = value;
k3 = key;
}
};
// O(n)
for(var key in obj){
// note 3
insertKey(key);
}
return [k1, k2, k3];
}
https://jsfiddle.net/DerekL/pzatq729/
请不要将代码复制粘贴到作业中作为解决方案。一旦你完全理解它,就重写代码。
注意:
Object.prototype
继承的。答案 2 :(得分:0)
如果您只是将Object.values
更改为Object.keys
并使用该键从原始对象中进行选择,则可以避免上一次循环。
let objToCheck = {
a: 2,
b: 5,
c: 9,
d: 33,
e: 4,
f: 8,
g: 3,
h: 10
};
function findBig3(obj){
return Object.keys(obj).sort((a,b) => {return obj[b]-obj[a]}).slice(0,3);
}
console.log(findBig3(objToCheck));