你有一个数组
nums
,它只包含 正 整数,所有正整数的数位长度都 相同 。两个整数的 数位不同 指的是两个整数 相同 位置上不同数字的数目。
请你返回
nums
中 所有 整数对里,数位不同之和。示例 1:
输入:nums = [13,23,12]
输出:4
解释:
计算过程如下:
- 13 和 23 的数位不同为 1 。
- 13 和 12 的数位不同为 1 。
- 23 和 12 的数位不同为 2 。
所以所有整数数对的数位不同之和为1 + 1 + 2 = 4
。示例 2:
输入:nums = [10,10,10,10]
输出:0
解释:
数组中所有整数都相同,所以所有整数数对的数位不同之和为 0 。
思路
这题拿到手一看,两层循环肯定会超时,所以考虑一次枚举,对每个数,我们需要判断它的每个数位和其它数的相同数位上不同的个数,也就是组合数,所以我们可以从头开始遍历数组,对每个数我们可以判断它的每个数位上的数字和前面已经遍历过的数的每个数位上的不同的数字的数目,换句话说,我们设置一个二维数组hash【10】【10】,x坐标代表每个数的第x位,y坐标表示这个位上的数字y,hash【x】【y】存储第x位上数字y出现的次数,例如hash【4】【5】就是第四位上数字5出现的次数。 这样每次遍历到一个数时对它每个位上的数字进行判断,计算和它不同的组合数加到res中去,同时将当前数字位上的数字加到hash数组中去,这样循环即可求解。解题过程
像上面说的,循环一次遍历每个数,对每个数,我们从最低位上的数字开始一一判断,设置变量base存储当前位,对当前位上的数字y,我们从0到9循环一次判断数组hash[base][j]将j和y不同的数加到结果当中去,然后将hash[base][y]加1,如此不断循判断即可得出答案。
class Solution {
public:
long long sumDigitDifferences(vector<int>& nums) {
int hash[10][10]={0};
long long res=0;
for(int i=0;i<nums.size();i++)
{
int base=0;//base存储从低开始第几位
int x=nums[i];
while(x)
{
int y=x%10;//y存储当前位上的数字
x/=10;
for(int j=0;j<10;j++)
{
if(j==y)
continue;
res+=hash[base][j];//+组合数
}
hash[base][y]++;
base++;
}
}
return res;
}
};