1. 程式人生 > 其它 >[LeetCode] 1182. Shortest Distance to Target Color

[LeetCode] 1182. Shortest Distance to Target Color

You are given an arraycolors, in which there are three colors:1,2and3.

You are also given some queries. Each query consists of two integersiandc, returnthe shortest distance between the given indexiand the target colorc. 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 題目總結