[英]Javascript: Concise way to fill sparse array with object
I am using an array to store objects (directed edges between nodes) and would like to use the an array to store the objects such that I can use the index of the array to refer to the object id.我正在使用一个数组来存储对象(节点之间的有向边),并且想使用一个数组来存储对象,这样我就可以使用数组的索引来引用 object id。
/**
* Take a graph where
* @param {number} N: The number of Nodes of in the graph
* @param {number[][]} trust: an array of directed edges trust [[a,b]] draws 'a trusts b'
* @return {number}
*/
var findJudge = function(N, trust) {
let nodes = [
{
trusts: {},
trustedBy: {}
}
]
trust.forEach(pair => {
nodes[pair[0]].trusts = pair[1]
nodes[pair[1]].trusted = pair[0]
})
return -1
};
Sample input: N = 2
and trust = [[1,2]]
errors because nodes[2]
doesn't exist yet at runtime.示例输入: N = 2
和trust = [[1,2]]
错误,因为nodes[2]
在运行时还不存在。
I would like to avoid pre-filling the array with null values if possible in the event that N is a really large number.如果可能的话,我想避免用 null 值预先填充数组,以防 N 是一个非常大的数字。 Perhaps this is not the proper data structure for filling sparse adjacency lists.也许这不是填充稀疏邻接表的正确数据结构。 Is there a way to say var x = new Array(of type object, of length N)
?有没有办法说var x = new Array(of type object, of length N)
?
Im open to any and all solutions.我对任何和所有解决方案持开放态度。
Edit to show context of problem https://leetcode.com/problems/find-the-town-judge/description/编辑以显示问题https://leetcode.com/problems/find-the-town-judge/description/的上下文
I would like to avoid pre-filling the array with null values if possible in the event that N is a really large number.如果可能的话,我想避免用 null 值预先填充数组,以防 N 是一个非常大的数字。
You can avoid such extreme case by first checking the size of the trust
argument.您可以通过首先检查trust
参数的大小来避免这种极端情况。 If there is a solution, then at least trust.length >= N-1
.如果有解决方案,那么至少trust.length >= N-1
。
If however that test passes, then you will anyway need to look at all entries of trust
to determine whether there is a judge, and who it is.但是,如果该测试通过,那么您无论如何都需要查看所有trust
条目,以确定是否有法官,以及法官是谁。 So then it does not increase the time complexity of the work if you also create all N nodes, before even iterating over trust
.因此,如果您还创建所有 N 个节点,甚至在迭代trust
之前,它不会增加工作的时间复杂度。
Secondly, your code would currently overwrite information, so that you can only store one trusted person and one trusted-by person per node.其次,您的代码当前会覆盖信息,因此每个节点只能存储一个受信任的人和一个受信任的人。 What you really need is that trusted
and trustedBy
can store multiple entries;您真正需要的是trusted
和trustedBy
可以存储多个条目; at least when you want to make a double-threaded graph.至少当你想制作一个双线程图时。
But when you really think about it, you would have enough information if you would only know the count of trusted
and the count of trustedBy
a node has.但是当你真正考虑它时,如果你只知道一个节点的trusted
数量和trustedBy
的数量,你就会得到足够的信息。 The judge must be the one for which the trusted
count is zero and the trustedBy
count is N-1.法官必须是trusted
计数为零且trustedBy
计数为N-1 的人。 There cannot be two of those, as that would be a contradiction.不可能有两个,因为那将是一个矛盾。
So, you can avoid creating the graph.因此,您可以避免创建图表。 It is enough that you just store counts, that start with 0.只存储从 0 开始的计数就足够了。
As in JavaScript array indices start with zero and not 1, your nodes
array would be indexed by one less than the actual person-id that is used in the trust
array.就像在 JavaScript 数组索引从零开始而不是 1 一样,您的nodes
数组的索引将比trust
数组中使用的实际人员 ID 小一。
Here is how that code could look:以下是该代码的外观:
var findJudge = function(N, trust) { // Quick exit, to avoid unnecessary looping if (trust.length < N - 1) return -1; // Create all nodes (with index one less -- starting at 0) let nodes = Array.from({ length: N }, () => ({ trusts: 0, trustedBy: 0 })); // Count trust relationships in both directions trust.forEach(([trustedBy, trusted]) => { nodes[trustedBy - 1].trusts++; nodes[trusted - 1].trustedBy++; }); // The only judge meets the following requirements // Add one to the found judge to go from 0-based to 1-based. return nodes.findIndex(node => node.trusts == 0 && node.trustedBy == N - 1) + 1 || -1; }; console.log(findJudge(3, [[1,2],[3,2],[1,3]]));
If you care about speed, then replace all loops with old-style for
loops, and instead of the array of objects ( trust
), use two simple arrays of counts ( trusts
and trustedBy
), as arrays of integers usually lead to better execution times than arrays of objects.如果您关心速度,则将所有循环替换为旧式for
循环,而不是对象数组 ( trust
),使用两个简单的计数 arrays ( trusts
和trustedBy
),因为 arrays 整数通常会导致更好的执行时间比 arrays 的对象。
as per @Bergi suggestion I simply check if object exists or not and create it.根据@Bergi 的建议,我只需检查 object 是否存在并创建它。 Still curious to other suggestions if anyone has any other javascript wizardry如果有人有任何其他 javascript 魔法,仍然对其他建议感到好奇
var findJudge = function(N, trust) {
function node() {
trusts: {}
trustedBy: {}
}
let nodes = []
trust.forEach(pair => {
pair.forEach(element => {
if (nodes[element] === undefined)
nodes[element] = new node()
})
nodes[pair[0]].trusts = pair[1]
nodes[pair[1]].trusted = pair[0]
})
return -1
};
Would have posted this as a comment however comments don't allow for code block formatting.会将此作为评论发布,但评论不允许代码块格式化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.