java - 在 Java 中将字符串集合复制到另一个字符串的时间复杂度
问题描述
我有几个关于 Java 的 add 函数如何Collection
处理字符串的问题。例如,在下面的代码片段中,我将一个List
字符串复制到一个HashSet
. 在这种情况下,最坏情况下的总时间复杂度是多少?是 O(M x N) 还是 O(N),其中 M 是列表中任意字符串的最大长度,N 是列表中字符串的总数。
public HashSet<String> createDict(List<String> wordList) {
HashSet<String> wordDict = new HashSet<>();
for(String word : wordList) {
wordDict.add(word);
}
return wordDict;
}
如果我使用下面的代码而不是循环,时间复杂度会完全相同吗?
HashSet<String> wordDict = new HashSet<>(wordList);
解决方案
字符串的长度与在集合之间复制元素无关。实际上,您不会复制字符串本身,而是复制对它们的引用。所以复杂度将是 O(N)。
当谈到第二个问题时new HashSet<>(wordList)
- 这个调用将比循环更快。这样做的原因是,在HashSet(Collection)
构造函数中,它首先检查该集合的大小,并以此为基础从 initialCapacity 开始。这样它就不必经常调整底层 HashMap 的大小。
对于那些好奇而懒得搜索的人,这是HashSet
有问题的构造函数:
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
addAll
从AbstractCollection
:_
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
因此,如果您要在示例代码中设置 initialCapacity,您将获得相同的性能,如下所示:
public HashSet<String> createDict(List<String> wordList) {
int initialCapacity = Math.max((int) (wordList.size()/.75f) + 1, 16);
HashSet<String> wordDict = new HashSet<>(initialCapacity );
for(String word : wordList) {
wordDict.add(word);
}
return wordDict;
}
推荐阅读
- reactjs - 无法创建动态下拉列表,因为 useState 首先返回 null,然后返回数据
- sql - 通过在 Oracle SQL 中的数据之间添加文本来更新 SQL 列数据
- python - 如何组织这个 python 结构?
- java - CrudRepostiroy findBy 查询/方法根据原始类型值获取记录,这是一个 ArrayList
- sql - 在 SQL 视图中填充缺失的数据集
- dependencies - 在 `dpkg -i` 上,一个包引用依赖项而不是在目录中找到的依赖项
- node.js - TypeScript 生成函数
- reactjs - 页面加载时的弹出框问题
- python - 如何在 pyspark 2.3.2 中使用 lit,lower,trim 等功能
- javascript - 在 CSS 中使用 Ajax 成功数据显示带有在表单中输入的值的预览