Java 中所有对的数字差总和

2025年5月12日 | 阅读 5 分钟

给定一个正数 整数 数组,其中每个整数具有相同数量的数字。两个整数在相同位置出现的不同数字的数量称为它们之间的数字差。

应返回数组中每对数字之间数字差的总和。

示例 1

输入

arr = [12, 34]

输出

所有数字对的数字差总和 4

解释

12 的数字是:[1, 2]

34 的数字是:[3, 4]

因此,成对的绝对差

|1 - 3| = 2

|2 - 4| = 2

所以总和是:2 + 2 = 4

示例 2

输入

arr = [23, 45, 67]

输出

所有数字对的数字差总和 12

解释

对是:(23, 45), (23, 67), (45, 67)

它们之间的差是

|2 - 4| + |3 - 5| = 2 + 2 = 4

|2 - 6| + |3 - 7| = 4 + 4 = 8

|4 - 6| + |5 - 7| = 2 + 2 = 4

所以总和是:4 + 8 + 4 = 12

示例 3

输入

arr = [101, 202]

输出

所有数字对的数字差总和 2

解释

101 的数字是:[1, 0, 1]

202 的数字是:[2, 0, 2]

成对的绝对差是

|1 - 2| = 1

|0 - 0| = 0

|1 - 2| = 1

所以总和是:1 + 0 + 1 = 2

方法:使用频率数组表示数字

为了优化比较过程,该程序使用二维频率数组跟踪所有整数中特定位置上每个数字的出现次数。它利用嵌套循环通过模运算快速提取数字来计算数字差,而无需显式创建对。该方法对于中等输入规模是有效的,因为它保证了 O(n * d + d * 100) 的复杂度,其中 n 是数组大小,d 是最大数字长度。基于位置的频率跟踪消除了重复计算的需要,并且使用数字频率的组合乘法来计算最终总和。

算法

步骤 1:鉴于数组中的每个数字都具有相同的长度,我们可以通过查看数组的第一个数字来确定其长度。

步骤 2:数字出现在所有整数的给定位置的次数由 digitFreq[pos][digit] 的值表示,可以将其创建为二维数组。

步骤 3:查找数组中每个整数在每个位置的数字,然后相应地更新 digitFreq 数组。

步骤 4:通过考虑不同数字频率的乘积来确定每个位置上存在差异的对的数量。

实施

输出

 
Therefore the Total sum is: 6   

复杂度分析

上述代码的时间复杂度为 O(N*D),其中 D 是数字的位数,N 是数组中的元素数量。空间复杂度为 O(N)。

方法:暴力成对比较算法

该代码使用具有 O(n² * d) 复杂度的暴力成对比较方法,遍历数组中的每个唯一对。通过比较相应的位置并计算绝对差,它使用模 (%) 和除法 (/) 运算来提取数字。为了计算最终总和,嵌套循环确保处理每一对并将差值相加。与基于频率的方法相比,该方法消除了额外的数据结构,但会进行冗余计算。尽管这种方法易于使用,但其二次时间复杂度使其对于大型数据集无效。

算法

步骤 1:初始化 res = 0。

步骤 2:假设每个数字都有相同数量的位数,则确定第一个数字的位数 (d)。

步骤 3:逐一遍历数组中的每对数字 (i, j)。

步骤 4:从右到左逐个比较每对数字的匹配数字。

步骤 4.1:从两个数字中分别移除最后一个数字。

步骤 4.2:计算其绝对差后,将其添加到 res。

步骤 4.3:从每个数字中移除最后一个数字。

步骤 5:返回 res 作为所有数字差异的总和。

实施

输出

 
Total sum: 6   

复杂度分析

上述代码的时间复杂度为 O(N2),其中 N 是数组中的元素数量。空间复杂度为 O(1)。


下一主题DTO Java