我的问题是关于字典的常量O(1)查找时间。
我有一个键/值对的字典。我有一个要迭代的元素列表。对于每个条目,我要检查它是否在字典中,如果不在,我要添加它,否则我将简单地传递。这是常数时间还是线性时间?
因为我在遍历整个字典,但是我知道在字典中查找是O(1)?-这让我很困惑!
我真正的问题是,总的时间复杂度是O(N^2)吗?因为对于列表中的每一项,我都要检查整个字典,看它是否存在,如果不存在,我就把每一项都添加到字典中。
总体复杂度为O(n)。您正在执行n查找,每个查找花费O(1)时间,总的时间复杂度为O(n×1) =O(n)。
对于每个条目,我想检查它是否在字典中,如果不在字典中,我想添加它…
边注,检查和添加在不同的步骤是一个常见的代码气味。通常最好直接尝试插入。如果密钥已经存在,则插入将失败,不需要先检查。这更有效,因为它只执行一次查找而不是两次查找——毕竟,插入必须执行与键检查完全相同的查找,以确定要插入的位置。先检查只会重复工作。
在最坏的情况下,它不仅提高了效率,而且提高了正确性。如果字典由多个线程访问,则检查-插入访问模式可能导致检查时间到使用时间(TOCTOU)错误。也就是说,您可以检查键是否存在;它没有,所以你尝试插入它;但与此同时,另一个线程在你不注意的时候潜入并插入了相同的键,你覆盖了另一个线程的条目。
另一个常见的TOCTOU错误是检查文件是否存在,如果不存在则创建它。有关更多详细信息和示例,请参阅常见弱点枚举367 - TOCTOU竞争条件。
当我们说在字典中查找是O(1)时,这意味着在字典中查找时执行的操作比字典的大小要少得多(不需要输入被认为是操作的细节)
如果执行n次查找,则在字典的大小范围内执行许多操作。所以你说它是O(n)其中n是字典的大小
在这种情况下,0符号只是一种相对度量,用于查看与输入的大小相比执行了多少操作。
换句话说,O符号是我们用来表示算法运行所需时间的语言。它是我们如何比较解决问题的不同方法的效率。当输入变大时,我们用0符号来表示运行时相对于输入的增长速度。
有关正式定义,请查看此处。
现在我不知道你在问什么,但是,要实现代码是:
foo_list = [1, 2, 3, 4, 5]
foo_dict = {1: "1", 4: "4", 6: "6"}
for i in foo_list:
if i not in foo_dict:
foo_dict[i] = str(i)