每日一道leetcode(2026.04.17):镜像对之间最小绝对距离

0 阅读3分钟

1. 题目

给你一个整数数组 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 <= 10e5 1 <= nums[i] <= 10e9

2. 分析

这道题我一开始的思路是按照最小距离做逐个遍历比较,比如,当前最小距离为1,用index为0的数值和0+1对应下标的数值比较,用index为1的数值和1+1对应下标的数值比较,如果遍历到最后也没有匹配上,则最小距离自增1,直到遍历完所有的场景。

最终的执行效果是有超时的用例。 在这里插入图片描述 然后思考了一下,通过一层nums遍历来完成,每个数值对应的镜像值是固定的,遍历到当前值是,找他它对应的镜像值,取最后一次出现的下标,计算出距离,以此遍历取过程中的最小值。

这儿遇到过一些问题,比如120的镜像值是21,但21的镜像值是12,两者不是一一对应的,而是多对一的。这个其实不是问题的重点,而是我忽略了一个条件,0 <= i < j < nums.length,并且 reverse(nums[i]) == nums[j]。nums[j]其实是个定值,如果从大方向往小方向进行遍历,这样只需要计算出当前值的镜像值,然后再判断镜像值是否在前面遍历的数据中出现过,出现了则取最后一次出现的下标,就能算出最小的距离,一直到遍历结束,求出最小的距离值即可。

3. 代码实现

class Solution {
    public int minMirrorPairDistance(int[] nums) {
        int minDistance = Integer.MAX_VALUE;
        Map<Integer, Integer> lastIndexMap = new HashMap<>();
        int val, mirror;
        for (int i = nums.length - 1; i >= 0; i--) {
            val = nums[i];
            // 数值对应的镜像数值
            mirror = reverse(val);
            if (lastIndexMap.containsKey(mirror)) {
                minDistance = Math.min(minDistance, lastIndexMap.get(mirror) - i);
            }
            lastIndexMap.put(val, i);
        }
        return minDistance == Integer.MAX_VALUE ? -1 : minDistance;
    }

    public static int reverse(int num) {
        if (num < 10) {
            return num;
        }
        char[] charArray = String.valueOf(num).toCharArray();
        char[] reverseArray = new char[charArray.length];
        for (int i = 0; i < charArray.length; i++) {
            reverseArray[i] = charArray[charArray.length - i - 1];
        }
        return Integer.parseInt(new String(reverseArray));
    }
}

在这里插入图片描述

4. 总结

按照我过程中的理解,如果是一个或的关系,二者若a为b的镜像,或b为a的镜像,那么解题思路又不一样,要保存所有出现的可能逆镜像值的下标。再者,如果nums数组声明为一个环形数组,那么计算距离的方式又得变化一下。