【LeetCode - 1182】与目标颜色间的最短距离

1、题目描述

在这里插入图片描述

2、解题思路

  题意:找出特定颜色中最靠近指定位置的那一个,并且求出这个距离。

  对于 queries = [[1,3],[2,2],[6,1]],其中[1,3] 的 1 表示指定位置,3 表示特定颜色,即在 colors 中颜色为 3 的所有索引中,找到最靠近位置 1 的那个,并求出这个最短距离。

  把三种颜色在 colors 中的索引位置分别标记出来,比如:colors = [1,1,2,1,3,2,2,3,3]

  那么三种颜色索引数组为:

  int[] one = {0,1,3}
  int[] two = {2,5,6}
  int[] three = {4,7,8}

  于是问题就转化为:从数组(one\two\three 三者其一)中找到最靠近目标值 key 的元素,并求出这个元素和 key 的差值绝对值。

  选择哪个数组就看 queries[i][1],目标值 key 就是queries[0][1]

  接下来就是遍历 queries

  1、对于遍历到的queries[i],从 queries[i][1] 判断待搜索数组是 one、two 还是 three;

  2、使用二分法,从数组中找是否存在 queries[i][0] 的值;

  3、如果数组中存在 queries[i][0] ,说明此时的距离为 0;

  4、如果数组中不存在 queries[i][0],则有三种情况:

  4.1 queries[i][0] 比数组最小值还小,那么此时最短距离就是 queries[i][0] 和最小值的差的绝对值;

  4.2 queries[i][0] 比数组最大值还大,那么此时最短距离就是 queries[i][0] 和最大值的差的绝对值;

  4.3 queries[i][0] 比最小值大,比最大值小。那么,queries[i][0] 肯定在某个索引 idx 和 idx+1 的值之间,我们计算 queries[i][0] 和第 idx 位元素差值绝对值,再计算 queries[i][0] 和 idx+1 位元素差的绝对值,最小的那个就是最小距离。

3、解题代码

class Solution {
        public List<Integer> shortestDistanceColor(int[] colors, int[][] queries) {
        List<Integer> ans = new ArrayList<>();
        if (queries.length == 0) {
            return ans;
        }
        Map<Integer, List<Integer>> map = new HashMap<>();
        map.put(1, new ArrayList<>());
        map.put(2, new ArrayList<>());
        map.put(3, new ArrayList<>());

        for (int i = 0; i < colors.length; i++) {
            map.get(colors[i]).add(i);
        }

        for (int[] query : queries) {
            List<Integer> ls = map.get(query[1]);   // 数组 ls 保存的是 query[1] 颜色在 colors 中的所有位置索引
            if (ls.size() == 0) {   // 不存在这个颜色
                ans.add(-1);
                continue;
            }

            // 在 ls 中有没有 query[0] 这个值
            int index = Collections.binarySearch(ls, query[0]);

           if (index >= 0) { // ls 中存在 key
                // 既然 ls 中存在 key,说明 key 和 ls 中差值最小的就是 0
                ans.add(0);
            } else { // list 不存在 key,此时 index 为:-insertPoint-1
                // insertPoint 表示 ls 中,比 key 大的最小值的索引
                int insertPoint = -index - 1;   // index = - insertPoint - 1;
                if (insertPoint == ls.size()) {
                    // 说明 key 比 ls 中最大值还大,那么 ls 中和 key 的最小差值就是 key 和最大的那个之差
                    ans.add(query[0] - ls.get(insertPoint - 1));
                } else if (insertPoint == 0) {
                    // 说明 key 比 ls 中最小值还小,那么 ls 中和 key 的最小差值就是最小元素 - key
                    ans.add(ls.get(0) - query[0]);
                } else {
                    // 说明 key 比 ls 中最小值大,比最大值小
                    ans.add(Math.min(ls.get(insertPoint) - query[0], query[0] - ls.get(insertPoint - 1)));
                }
            }
        }
        return ans;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值