英文:
Big O notation for .forEach with .find
问题
这段代码的时间复杂度是O(N),而不是O(N^3)。尽管它包含了一个.forEach
循环以及两个.find()
操作,但这些操作在这种情况下不会导致O(N^3)的复杂度。.forEach
循环遍历_data.validatorInfo.result.validators
数组,其中N是数组的长度。内部的.find()
操作是在不同的数组上执行的,但它们是线性操作,因此它们的复杂度仍然是O(N)。因此,整体的时间复杂度是O(N)。
英文:
What is the big O notation for the following code?
_data.validatorInfo.result.validators.forEach((_validator) => {
let del = {
delegation: _data.delegations.result.delegation_responses.find(
res => res.delegation.validator_address === _validator.operator_address
),
validator: _validator,
rewards: _data.totalRewards.result.rewards.find(
re => re.validator_address === _validator.operator_address
)
}
result.delegations.push(del);
})
Since it has a .forEach
and two .find()
operations nested, can I assume it is O(N^3)?
答案1
得分: 2
你遍历所有的validators
(V),对于每一个,遍历delegation_responses
(P)和rewards
(W),直到找到特定的元素,这平均意味着要遍历数组的一半。
这将给你V * (P + W)/2
。大O符号忽略常数因子(将它们设为1),因此得到O(V * (P + W))
。此时,可以进行以下讨论:
-
如果P和W与V相比非常小(数量级上),您可以认为它们行为类似于常数,并且只稍微扩展了主要因素V,从而获得有效线性复杂度
O(N)
,其中N是验证者的数量。 -
如果V非常小(再次是数量级上)与P和/或W相比,您将获得
O(N)
或O(N + M)
,其中N和M是响应/奖励的数量,再次认为V行为类似于一个常数。 -
如果它们都差不多大(或者你不能对它们的大小做出假设),你将得到
O(N * 2N)
,也就是O(N²)
。
英文:
You go through all validators
(V), for each of them going through delegation_responses
(P) and rewards
(W) until a certain element is found, which on average means to go through half of the array .
This would give you V * (P + W)/2
. Big O ignores constants factors (sets them to 1), so that gives you O(V * (P + W))
. And at that point, you can start arguing:
-
If P and W are very small compared to V (like orders of magnitude), you would argue that they behave like constants and only slightly scale the driving factor V, and you deal with effectively linear complexity
O(N)
, where N is the number of validators. -
If V is very small (again, orders of magnitude) compared to P and/or W, you would get
O(N)
orO(N + M)
, where N and M are number of responses/rewards, again arguing that V behaves like a constant. -
If they are all about the same size (or you cannot make assumptions about their size), you get
O(N * 2N)
, which isO(N²)
.
答案2
得分: 2
你的复杂度是
O(N*(M+Q))
,其中
- N 是
_data.validatorInfo.result.validators.length
- M 是
_data.delegations.result.delegation_responses.length
- Q 是
_data.totalRewards.result.rewards.length
可以假设这个复杂度
- 如果 N ~ M+Q,则为二次复杂度
- 如果 N >> M + Q,则为线性复杂度
英文:
Your complexity is
O(N*(M+Q))
, where
- N is
_data.validatorInfo.result.validators.length
- M is
_data.delegations.result.delegation_responses.length
and - Q is
_data.totalRewards.result.rewards.length
You can assume that this
- is quadric if N ~ M+Q
- linear if N >> M + Q
答案3
得分: 1
不直接回答你的问题,我想指出性能可以很容易地改进。一种常见的方法是使用哈希表(Object
或Map
)来查找你要查找的项目。
const delegations = new Map();
_data.delegations.result.delegation_responses.forEach((res) => {
delegations.set(res.delegation.validator_address, res);
});
const rewards = new Map();
_data.totalRewards.result.rewards.forEach((re) => {
rewards.set(re.validator_address, re);
});
_data.validatorInfo.result.validators.forEach((_validator) => {
result.delegations.push({
delegation: delegations.get(_validator.operator_address),
validator: _validator,
rewards: rewards.get(_validator.operator_address),
});
});
使用与Radu Diță的回答相同的字母。
- N为
_data.validatorInfo.result.validators.length
- M为
_data.delegations.result.delegation_responses.length
- Q为
_data.totalRewards.result.rewards.length
这个改进版本将导致复杂度为O(N+M+Q)
。
如果你的情况允许,你可能可以使用以下方式:
result.delegations = _data.validatorInfo.result.validators.map(...);
英文:
Rather than answering your question directly, I want to point out that performance can be improved very easily. A common way to do this would be to use a hash table (Object
or Map
) to find the items you're looking for.
const delegations = new Map();
_data.delegations.result.delegation_responses.forEach((res) => {
delegations.set(res.delegation.validator_address, res);
});
const rewards = new Map();
_data.totalRewards.result.rewards.forEach((re) => {
rewards.set(re.validator_address, re);
});
_data.validatorInfo.result.validators.forEach((_validator) => {
result.delegations.push({
delegation: delegations.get(_validator.operator_address),
validator: _validator,
rewards: rewards.get(_validator.operator_address),
});
});
Using the same letters as the answer of Radu Diță
> - N is _data.validatorInfo.result.validators.length
> - M is _data.delegations.result.delegation_responses.length
and
> - Q is _data.totalRewards.result.rewards.length
This improved version would result in complexity O(N+M+Q)
.
You might be able to use
result.delegations = _data.validatorInfo.result.validators.map(...);
if your scenario allows for it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论