我最近在接受采访时被问到了一个问题。如何在十亿字符串列表中找到十大最长的字符串? 我的答案是我们需要编写一个Comparator来比较2个字符串的长度,然后使用TreeSet(Comparator)构造函数。 一旦开始在Treeset中添加字符串,它将按照定义的比较器的排序顺序进行排序。 然后只需弹出Treeset的前10个元素。
面试官对此并不满意。争论的焦点是,要拥有十亿字符串,我必须使用超级计算机。
是否有其他数据结构可以处理这类数据?
答案 0 :(得分:2)
鉴于你所说的面试官说你需要一台超级计算机,我会假设这些字符串会一次串成一串。
由于不知道单个字符串的大小(它们可能是整本书),因为它的大小很大,我会从流中一次一个地读取它们。然后,我将当前字符串与之前找到的前十个最长字符串的有序列表进行比较,并将其相应地放入有序列表中。然后我将从列表中删除最小的长度,然后继续阅读下一个字符串。这意味着一次只存储11个字符串,当前前10个和当前正在处理的字符串。
答案 1 :(得分:0)
大多数语言都有内置排序,速度非常快。
stringList.sort(key=len)
python中的会起作用。然后抓住前10个元素。
此外,你的面试官听起来也很落后。现在十天的十亿字符串非常小
答案 2 :(得分:0)
答案 3 :(得分:0)
关键是你不需要存储所有字符串。
让我们想一个简化的版本:找到最长的2个字符串(假设没有领带情况)
您可以随时使用2个变量s1
& s2
,其中s1
是您目前遇到的最长字符串,s2
是第二长的
然后您使用O(N)
逐个阅读字符串,在可能的情况下替换s1
或s2
。这使用O(2N)
= O(N)
对于前10个字符串,它与前2个字符串一样愚蠢。您仍然可以在O(10N)
= O(N)
中执行此操作,并且只存储10个字符串。
有一种更快的方式描述如下,但对于给定的常数,如2或10,您可能不需要它。
对于一般的前K个字符串,您可以在C ++中使用类似set
的结构(具有更高优先级的更长时间)来存储前K个字符串,当新字符串出现时,您只需插入它,并且删除最后一个,都使用O(lg K)
。总而言之,您可以在O(N lg K)
O(K)
空格内完成此任务。