[LeetCode] 1182. Shortest Distance to Target Color

You are given an array colors, in which there are three colors: 12 and 3.

You are also given some queries. Each query consists of two integers i and c, return the shortest distance between the given index i and the target color c. If there is no solution return -1.

Example 1:

Input: colors = [1,1,2,1,3,2,2,3,3], queries = [[1,3],[2,2],[6,1]]
Output: [3,0,3]
Explanation: 
The nearest 3 from index 1 is at index 4 (3 steps away).
The nearest 2 from index 2 is at index 2 itself (0 steps away).
The nearest 1 from index 6 is at index 3 (3 steps away).

Example 2:

Input: colors = [1,2], queries = [[0,3]]
Output: [-1]
Explanation: There is no 3 in the array.

Constraints:

  • 1 <= colors.length <= 5*10^4
  • 1 <= colors[i] <= 3
  • 1 <= queries.length <= 5*10^4
  • queries[i].length == 2
  • 0 <= queries[i][0] < colors.length
  • 1 <= queries[i][1] <= 3

与目标颜色间的最短距离。

给你一个数组 colors,里面有  1、2、 3 三种颜色。

我们需要在 colors 上进行一些查询操作 queries,其中每个待查项都由两个整数 i 和 c 组成。

现在请你帮忙设计一个算法,查找从索引 i 到具有目标颜色 c 的元素之间的最短距离。

如果不存在解决方案,请返回 -1。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-distance-to-target-color
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这道题我提供一个二分法的思路,算是比较好懂吧。这道题还有一个动态规划的做法,日后有机会再补充。

这个题目问的是对于每一个 query,query[0] 代表的是要找的某个 index,query[1] 代表的是要找的 color。也就是说我们每一个 query 要找的是离某个 index 最近的 color 在哪里。注意到 input 数组是无序的,但是因为找的元素是确定的,所以我们先用一个 hashmap 把 input 数组中的不同数字在 input 数组中出现的下标记录一下。注意到对于每个元素来说,我们记录 index 的 list 最后是有序的,所以我们二分的范围也就是在这些 list 中。

所以对于一个要找的元素来说,首先我们看一下他是否存在于hashmap,如果不存在直接就返回 -1 了。如果存在,我们就在 hashmap 中找到的 list 中做二分法。注意最后二分跳出的时候需要有特判,因为要找的某个 index 很有可能在list的左边或者右边。所以最后的特判是如果左指针/右指针在合法范围内,我们再去判断哪个指针离 index 更近。

时间O(nlogn)

空间O(n)

Java实现

 1 class Solution {
 2     public List<Integer> shortestDistanceColor(int[] colors, int[][] queries) {
 3         HashMap<Integer, List<Integer>> map = new HashMap<>();
 4         // 记录每个color的index
 5         for (int i = 0; i < colors.length; i++) {
 6             int c = colors[i];
 7             map.putIfAbsent(c, new ArrayList<>());
 8             map.get(c).add(i);
 9         }
10 
11         List<Integer> res = new ArrayList<>();
12         for (int[] query : queries) {
13             int index = query[0];
14             int c = query[1];
15             // corner case
16             if (!map.containsKey(c)) {
17                 res.add(-1);
18             } else {
19                 res.add(binarySearch(index, map.get(c)));
20             }
21         }
22         return res;
23     }
24 
25     private int binarySearch(int index, List<Integer> list) {
26         int left = 0;
27         int right = list.size() - 1;
28         // left + 1 == right when exit from while loop
29         while (left + 1 < right) {
30             int mid = left + (right - left) / 2;
31             if (list.get(mid) == index) {
32                 return 0;
33             } else if (list.get(mid) < index) {
34                 left = mid;
35             } else {
36                 right = mid;
37             }
38         }
39         // System.out.println("left is " + left + " right is " + right);
40         int res = right;
41         if (right - 1 >= 0 && Math.abs(index - list.get(right - 1)) < Math.abs(index - list.get(right))) {
42             res = right - 1;
43         }
44         return Math.abs(list.get(res) - index);
45     }
46 }

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/14906687.html