Algorithm 共享至少一个数字的对数

Algorithm 共享至少一个数字的对数,algorithm,Algorithm,您将获得n数字,并且您必须找到对数,以便它们之间至少有一个数字是公共的 例如,对于5数字: 2837 2818 654 35 931 回答:6 这里的配对是(28372818),(2837,35),(2837931),(2818931),(654,35),(35931) 我的尝试:我采用了一种结构,它以十进制形式存储数字,以数组中的数字形式存储数字,并存储该数字中的位数 现在,对每个数字I进行哈希运算表示数组索引中的该数字0-9,并用以下所有数字检查是否有数字存在 我的尝试是O(n^2),速度

您将获得
n
数字,并且您必须找到对数,以便它们之间至少有一个数字是公共的

例如,对于5数字:

2837 2818 654 35 931
回答:6

这里的配对是
(28372818),(2837,35),(2837931),(2818931),(654,35),(35931)

我的尝试:我采用了一种结构,它以十进制形式存储数字,以数组中的数字形式存储数字,并存储该数字中的位数

现在,对每个数字I进行哈希运算表示数组索引中的该数字0-9,并用以下所有数字检查是否有数字存在


我的尝试是
O(n^2)
,速度很慢。还有其他算法可以更快地工作吗?

创建一个集合数组,每个集合对应一个数字

迭代您的数字,并将每个数字放在每个集合中,以表示其包含的数字

迭代所有10个集合,并将集合中的每个元素与同一集合中的所有其他元素组合。(或所有其他大于自身的元素,如果您不希望结果中出现(a,b)和(b,a)

我认为这仍然是O(n^2),但可以使用fork-join方法很好地并行化它

更新

刚刚意识到你只需要结果的数量。所以这就是所有集合的大小*size-1的总和。因为插入集合并获取其大小应该是线性的(我认为),这实际上可能是O(n)

另一次更新

如果你的数字是不同的,你只对对对的数量感兴趣,你甚至不需要集合,你只需要一个计数器

不起作用 从评论中:

Consider 1st pair in above questions test case (2837,2818), this will put first number in set containing digit 2 and 8 and same for 2818 now they are to be counted as one but counting in 2 and 8 will count it twice. I hope you understand what I am trying to say...

因此,这种方法不起作用……我想它可能对其他人有警示作用。

首先,我注意到公共数字的位置并不重要

在这种情况下,我用哈希表绘制了一个小算法:形成10个箱子,每个数字对应一个。然后,对于每个数字,将数字的ID(唯一地)放在每个箱子中,对应于每个数字。这个操作是O(n*k),k是数字的位数。最后,要形成所有对,请在每个箱子中取出对数字。要删除可能的双二进制,请将每对(a,b)用a排列
我认为最坏的情况实际上是O(n^2);事实上,我确实认为这一步的复杂度必须是O(n^2),因为你想要取所有对(最大n*(n+1)/2)。因此,最后的复杂度实际上是二次的。

了解这里的变量和常量是至关重要的

位数是一个常数(10)。所有数字集的数量(1024)也是一个常数。所有这些数字集对的数量(220,或大约一百万)也是一个常数。让我们利用这一点

让我们尝试将输入预处理为大小恒定(与输入大小无关)的数据结构中的“等效”表示形式。然后,根据定义,我们对该恒定大小结构所做的任何操作都是恒定时间操作,因此总运行时间仅由预处理阶段渐近确定

数据结构

创建一个包含1024个整数的数组,每个bucket(索引)对应一组数字;我们希望存储每个bucket中正好包含该组数字的输入数字的数量

例如,3606有数字0、3和6,因此它将被计算在bucket 20+23+26=73中

算法


预处理是显而易见的。取下一个数字(如
'3'
),将其转换为其值(如
3
),现在计算相应的位(如
1)您对一个值进行了哈希运算,但未能使用哈希表查找?我的解决方案工作正常,但在n较大时需要相当多的时间这不能比O快(n^2)因为你需要O(n^2)至少要在最坏的情况下生成答案。@GrigorGevorgyan-我假设问题中示例的答案是简单的
6
。您不必列出所有的对。@JirkaHanika是的,您是正确的对显示了更多和清晰的解释,只需要计数作为答案,即使在问题中也是粗体的简单地写为“对的数量”。枚举对,而不仅仅是计算对的数量,在最坏的情况下必然需要Ω(n²)的时间,因为有O(n²)其中。@larsmans你是对的,我刚刚意识到只需要对的数量。编辑了答案。@L.ppt数字可以很大是什么意思?你是说n可以很大?还是说每个数字都可以很大?如果n可以达到10^18,我想你有个问题。@L.ppt:什么十进制数字(不是数字!)大于9?所以数字最多有18位…因为这只是O()中的一个常量估计值,而不是一个很大的数字,这是非常不相关的。我认为在这种形式下,它与我提出的解决方案有相同的问题,但这一个可能是可以解决的。对不起,我错了。我以为你有两个计数对,它们有多个共同数字,但你没有。请你解释一下为什么你使用这种2^0+2^3+2^6的方法进行映射。我更感兴趣的是知道你是如何想到它的。任何固定的映射都可以,只要它从不将两组不同的数字映射到同一个代码。我选择这一个是为了节省空间、缓存友好,以及便于最后的嵌套迭代:有了这个特定的映射,数组中就没有“漏洞”(有效代码之间无非代码)最后但并非最不重要的一点是,在任何正常的体系结构中,这种编码每输入一个字符只需要少量的机器指令。不需要求幂运算,因为对于任何x,2^x=1向左移动x。@JirkaHanika,你能详细解释一下吗,我不清楚上面的解决方案,你能不能