在复杂度为O(n)的Javascript对象中查找3个最大值的键?
假设您有一个对象,例如:在复杂度为O(n)的Javascript对象中查找3个最大值的键?,javascript,algorithm,sorting,big-o,javascript-objects,Javascript,Algorithm,Sorting,Big O,Javascript Objects,假设您有一个对象,例如: let objToCheck = { a: 2, b: 5, c: 9, d: 33 }; 如何按升序返回三个最大值的键,在本例中是:['c','h','d'],以线性时间为单位?显然,您需要循环整个对象一次,以比较所有值,但我很难想出一个不涉及嵌套循环的解决方案,我认为它是O(n²)。到目前为止,我的解决方案是这样的: function findBig3 (obj){ const res = []; const largest = Obje
let objToCheck = {
a: 2,
b: 5,
c: 9,
d: 33
};
如何按升序返回三个最大值的键,在本例中是:['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
,当您在对象中循环时,执行某种类型的比较检查并根据需要重新分配,但我正在努力实现 如果您只是将Object.values
更改为Object.keys
并使用该键从原始对象中进行选择,则可以避免最后一个循环
让objToCheck={
答:2,,
b:5,
c:9,
d:33,
e:4,
f:8,
g:3,
h:10
};
函数findBig3(obj){
return Object.keys(obj).sort((a,b)=>{return obj[b]-obj[a]}).slice(0,3);
}
log(findBig3(objToCheck))
如果您只是将Object.values
更改为Object.keys
并使用该键从原始对象中进行选择,则可以避免最后一个循环
让objToCheck={
答:2,,
b:5,
c:9,
d:33,
e:4,
f:8,
g:3,
h:10
};
函数findBig3(obj){
return Object.keys(obj).sort((a,b)=>{return obj[b]-obj[a]}).slice(0,3);
}
log(findBig3(objToCheck))代码>此算法在O(n)中运行
请不要将代码复制粘贴到作业中作为解决方案。一旦完全理解代码,就重写它
注:
这假设对象查找为O(1)。这最终取决于它在解释器中的实现方式,但它通常低于O(logn)
这些条件当然可以优化。我将留给读者作为练习
通常我们应该检查键是否属于对象实例,但这里我将假设输入对象不是从object.prototype
继承的
该算法在O(n)中运行
请不要将代码复制粘贴到作业中作为解决方案。一旦完全理解代码,就重写它
注:
这假设对象查找为O(1)。这最终取决于它在解释器中的实现方式,但它通常低于O(logn)
这些条件当然可以优化。我将留给读者作为练习
通常我们应该检查键是否属于对象实例,但这里我将假设输入对象不是从object.prototype
继承的
您可以在一个数组中不断推送3个对象并对数组进行排序,假设所需的元素数k充分小于n,这可以平均提供线性效率
让objToCheck={
答:2,,
b:5,
c:9,
d:33,
e:4,
f:8,
g:3,
h:10
};
函数findBig3(obj){
var res=[-1,-1,-1];
用于(输入obj){
res[3]=obj[key];
res.sort(函数(a,b){返回b-a});
}
res.pop();
返回res;
}
log(findBig3(objToCheck))代码>您可以在一个数组中不断推送3个对象并对数组进行排序,假设您需要的元素数k足够小于n,这可以平均提供线性效率
让objToCheck={
答:2,,
b:5,
c:9,
d:33,
e:4,
f:8,
g:3,
h:10
};
函数findBig3(obj){
var res=[-1,-1,-1];
用于(输入obj){
res[3]=obj[key];
res.sort(函数(a,b){返回b-a});
}
res.pop();
返回res;
}
log(findBig3(objToCheck))
.sort
不是O(n)。.sort
不是O(n)。这与这完全没有区别。这与我们也可以创建一个包含4个元素的数组,并始终将最新的元素放在末尾,以避免调用.push
和.pop
@Derek朕會功夫 是的,那会更好,谢谢你的建议,代码更新。我们还可以创建一个包含4个元素的数组,并始终将最新的元素放在末尾,以避免调用.push
和.pop
@Derek朕會功夫 是的,那会更好,谢谢你的建议,代码更新。
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];
}