给你一个整数数组 nums。
镜像对 是指一对满足下述条件的下标 (i, j):
0 <= i < j < nums.length,并且reverse(nums[i]) == nums[j],其中reverse(x)表示将整数x的数字反转后形成的整数。反转后会忽略前导零,例如reverse(120) = 21。
返回任意镜像对的下标之间的 最小绝对距离 。下标 i 和 j 之间的绝对距离为 abs(i - j)。
如果不存在镜像对,返回 -1。
示例 1:
输入: nums = [12,21,45,33,54]
输出: 1
解释:
镜像对为:
- (0, 1),因为
reverse(nums[0]) = reverse(12) = 21 = nums[1],绝对距离为abs(0 - 1) = 1。 - (2, 4),因为
reverse(nums[2]) = reverse(45) = 54 = nums[4],绝对距离为abs(2 - 4) = 2。
所有镜像对中的最小绝对距离是 1。
示例 2:
输入: nums = [120,21]
输出: 1
解释:
只有一个镜像对 (0, 1),因为 reverse(nums[0]) = reverse(120) = 21 = nums[1]。
最小绝对距离是 1。
示例 3:
输入: nums = [21,120]
输出: -1
解释:
数组中不存在镜像对。
提示:
1 <= nums.length <= 10^51 <= nums[i] <= 10^9
分析:用一个哈希表记录出现过的数字,遍历 nums 数组,对每个数字进行镜像处理,检查镜像后的数字是否在哈希表中,若存在,则说明存在镜像对。统计镜像对数量即可。
cpp
class Solution {
public:
int minMirrorPairDistance(vector<int>& nums) {
int n=nums.size(),cnt=1,ans=10000000;
map<int,int>mp;
vector<vector<int>>vec;vec.push_back(vector<int>());
for(int i=0;i<n;++i)
{
if(mp[nums[i]]==0)mp[nums[i]]=cnt,cnt++,vec.push_back(vector<int>());
vec[mp[nums[i]]].push_back(i);
}
for(int i=0;i<n;++i)
{
int val=0,temp=nums[i];
while(temp)
val=val*10+temp%10,temp/=10;
// printf("i=%d val=%d num=%d\n",i,val,nums[i]);
if(mp[val]==0)continue;
int l=0,r=vec[mp[val]].size(),pos=-1;
while(l<r)
{
int mid=(l+r)/2;
if(vec[mp[val]][mid]>i)pos=mid,r=mid;
else l=mid+1;
}
if(pos==-1)continue;
pos=vec[mp[val]][pos];
// printf("pos=%d ans=%d\n",pos,ans);
ans=min(ans,pos-i);
}
if(ans==10000000)return -1;
return ans;
}
};