50
50
51
51
<!-- 这里可写通用的实现逻辑 -->
52
52
53
- 二分查找。
53
+ ** 方法一:预处理 **
54
54
55
- 先用哈希表记录每种颜色的索引位置。然后遍历 ` queries ` ,如果当前 ` color ` 不在哈希表中,说明不存在解决方案,此时此 ` query ` 对应的结果元素是 ` -1 ` 。否则,在哈希表中取出当前 ` color ` 对应的索引列表,二分查找即可。
55
+ 我们可以预处理出每个位置到左边最近的颜色 $1$,$2$,$3$ 的距离,以及每个位置到右边最近的颜色 $1$,$2$,$3$ 的距离,记录在数组 $left$ 和 $right$ 中。初始时 $left[ 0] [ 1 ] = left[ 0] [ 2 ] = left[ 0] [ 3 ] = -\infty$,而 $right[ n] [ 1 ] = right[ n] [ 2 ] = right[ n] [ 3 ] = \infty$,其中 $n$ 是数组 $colors$ 的长度。
56
+
57
+ 然后对于每个查询 $(i, c)$,最小距离就是 $d = \min(i - left[ i + 1] [ c - 1 ] , right[ i] [ c - 1 ] [ i] - i)$,如果 $d \gt n$,则不存在解决方案,此次查询的答案为 $-1$。
58
+
59
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $colors$ 的长度。
56
60
57
61
<!-- tabs:start -->
58
62
62
66
63
67
``` python
64
68
class Solution :
65
- def shortestDistanceColor (
66
- self , colors : List[int ], queries : List[List[int ]]
67
- ) -> List[int ]:
68
- color_indexes = defaultdict(list )
69
- for i, c in enumerate (colors):
70
- color_indexes[c].append(i)
71
- res = []
69
+ def shortestDistanceColor (self , colors : List[int ], queries : List[List[int ]]) -> List[int ]:
70
+ n = len (colors)
71
+ right = [[inf] * 3 for _ in range (n + 1 )]
72
+ for i in range (n - 1 , - 1 , - 1 ):
73
+ for j in range (3 ):
74
+ right[i][j] = right[i + 1 ][j]
75
+ right[i][colors[i] - 1 ] = i
76
+ left = [[- inf] * 3 for _ in range (n + 1 )]
77
+ for i, c in enumerate (colors, 1 ):
78
+ for j in range (3 ):
79
+ left[i][j] = left[i - 1 ][j]
80
+ left[i][c - 1 ] = i - 1
81
+ ans = []
72
82
for i, c in queries:
73
- if c not in color_indexes:
74
- res.append(- 1 )
75
- else :
76
- t = color_indexes[c]
77
- left, right = 0 , len (t) - 1
78
- while left < right:
79
- mid = (left + right) >> 1
80
- if t[mid] >= i:
81
- right = mid
82
- else :
83
- left = mid + 1
84
- val = abs (t[left] - i)
85
- if left > 0 :
86
- val = min (val, abs (t[left - 1 ] - i))
87
- if left < len (t) - 1 :
88
- val = min (val, abs (t[left + 1 ] - i))
89
- res.append(val)
90
- return res
83
+ d = min (i - left[i + 1 ][c - 1 ], right[i][c - 1 ] - i)
84
+ ans.append(- 1 if d > n else d)
85
+ return ans
91
86
```
92
87
93
88
### ** Java**
@@ -97,39 +92,144 @@ class Solution:
97
92
``` java
98
93
class Solution {
99
94
public List<Integer > shortestDistanceColor (int [] colors , int [][] queries ) {
100
- Map<Integer , List<Integer > > colorIndexes = new HashMap<> ();
101
- for (int i = 0 ; i < colors. length; ++ i) {
102
- int c = colors[i];
103
- colorIndexes. computeIfAbsent(c, k - > new ArrayList<> ()). add(i);
104
- }
105
- List<Integer > res = new ArrayList<> ();
106
- for (int [] query : queries) {
107
- int i = query[0 ], c = query[1 ];
108
- if (! colorIndexes. containsKey(c)) {
109
- res. add(- 1 );
110
- continue ;
95
+ int n = colors. length;
96
+ final int inf = 1 << 30 ;
97
+ int [][] right = new int [n + 1 ][3 ];
98
+ Arrays . fill(right[n], inf);
99
+ for (int i = n - 1 ; i >= 0 ; -- i) {
100
+ for (int j = 0 ; j < 3 ; ++ j) {
101
+ right[i][j] = right[i + 1 ][j];
111
102
}
112
- List<Integer > t = colorIndexes. get(c);
113
- int left = 0 , right = t. size() - 1 ;
114
- while (left < right) {
115
- int mid = (left + right) >> 1 ;
116
- if (t. get(mid) >= i) {
117
- right = mid;
118
- } else {
119
- left = mid + 1 ;
120
- }
103
+ right[i][colors[i] - 1 ] = i;
104
+ }
105
+ int [][] left = new int [n + 1 ][3 ];
106
+ Arrays . fill(left[0 ], - inf);
107
+ for (int i = 1 ; i <= n; ++ i) {
108
+ for (int j = 0 ; j < 3 ; ++ j) {
109
+ left[i][j] = left[i - 1 ][j];
121
110
}
122
- int val = Math . abs(t. get(left) - i);
123
- if (left > 0 ) {
124
- val = Math . min(val, Math . abs(t. get(left - 1 ) - i));
111
+ left[i][colors[i - 1 ] - 1 ] = i - 1 ;
112
+ }
113
+ List<Integer > ans = new ArrayList<> ();
114
+ for (int [] q : queries) {
115
+ int i = q[0 ], c = q[1 ] - 1 ;
116
+ int d = Math . min(i - left[i + 1 ][c], right[i][c] - i);
117
+ ans. add(d > n ? - 1 : d);
118
+ }
119
+ return ans;
120
+ }
121
+ }
122
+ ```
123
+
124
+ ### ** C++**
125
+
126
+ ``` cpp
127
+ class Solution {
128
+ public:
129
+ vector<int > shortestDistanceColor(vector<int >& colors, vector<vector<int >>& queries) {
130
+ int n = colors.size();
131
+ int right[ n + 1] [ 3 ] ;
132
+ const int inf = 1 << 30;
133
+ fill(right[ n] , right[ n] + 3, inf);
134
+ for (int i = n - 1; i >= 0; --i) {
135
+ for (int j = 0; j < 3; ++j) {
136
+ right[ i] [ j ] = right[ i + 1] [ j ] ;
125
137
}
126
- if (left < t. size() - 1 ) {
127
- val = Math . min(val, Math . abs(t. get(left + 1 ) - i));
138
+ right[ i] [ colors[ i] - 1] = i;
139
+ }
140
+ int left[ n + 1] [ 3 ] ;
141
+ fill(left[ 0] , left[ 0] + 3, -inf);
142
+ for (int i = 1; i <= n; ++i) {
143
+ for (int j = 0; j < 3; ++j) {
144
+ left[ i] [ j ] = left[ i - 1] [ j ] ;
128
145
}
129
- res . add(val) ;
146
+ left [ i ] [ colors [ i - 1 ] - 1 ] = i - 1 ;
130
147
}
131
- return res;
148
+ vector<int > ans;
149
+ for (auto& q : queries) {
150
+ int i = q[ 0] , c = q[ 1] - 1;
151
+ int d = min(i - left[ i + 1] [ c ] , right[ i] [ c ] - i);
152
+ ans.push_back(d > n ? -1 : d);
153
+ }
154
+ return ans;
155
+ }
156
+ };
157
+ ```
158
+
159
+ ### **Go**
160
+
161
+ ```go
162
+ func shortestDistanceColor(colors []int, queries [][]int) (ans []int) {
163
+ n := len(colors)
164
+ const inf = 1 << 30
165
+ right := make([][3]int, n+1)
166
+ left := make([][3]int, n+1)
167
+ right[n] = [3]int{inf, inf, inf}
168
+ left[0] = [3]int{-inf, -inf, -inf}
169
+ for i := n - 1; i >= 0; i-- {
170
+ for j := 0; j < 3; j++ {
171
+ right[i][j] = right[i+1][j]
172
+ }
173
+ right[i][colors[i]-1] = i
174
+ }
175
+ for i := 1; i <= n; i++ {
176
+ for j := 0; j < 3; j++ {
177
+ left[i][j] = left[i-1][j]
178
+ }
179
+ left[i][colors[i-1]-1] = i - 1
180
+ }
181
+ for _, q := range queries {
182
+ i, c := q[0], q[1]-1
183
+ d := min(i-left[i+1][c], right[i][c]-i)
184
+ if d > n {
185
+ d = -1
186
+ }
187
+ ans = append(ans, d)
188
+ }
189
+ return
190
+ }
191
+
192
+ func min(a, b int) int {
193
+ if a < b {
194
+ return a
195
+ }
196
+ return b
197
+ }
198
+ ```
199
+
200
+ ### ** TypeScript**
201
+
202
+ ``` ts
203
+ function shortestDistanceColor(
204
+ colors : number [],
205
+ queries : number [][],
206
+ ): number [] {
207
+ const n = colors .length ;
208
+ const inf = 1 << 30 ;
209
+ const right: number [][] = Array (n + 1 )
210
+ .fill (0 )
211
+ .map (() => Array (3 ).fill (inf ));
212
+ const left: number [][] = Array (n + 1 )
213
+ .fill (0 )
214
+ .map (() => Array (3 ).fill (- inf ));
215
+ for (let i = n - 1 ; i >= 0 ; -- i ) {
216
+ for (let j = 0 ; j < 3 ; ++ j ) {
217
+ right [i ][j ] = right [i + 1 ][j ];
218
+ }
219
+ right [i ][colors [i ] - 1 ] = i ;
220
+ }
221
+ for (let i = 1 ; i <= n ; ++ i ) {
222
+ for (let j = 0 ; j < 3 ; ++ j ) {
223
+ left [i ][j ] = left [i - 1 ][j ];
224
+ }
225
+ left [i ][colors [i - 1 ] - 1 ] = i - 1 ;
226
+ }
227
+ const ans: number [] = [];
228
+ for (const [i, c] of queries ) {
229
+ const d = Math .min (i - left [i + 1 ][c - 1 ], right [i ][c - 1 ] - i );
230
+ ans .push (d > n ? - 1 : d );
132
231
}
232
+ return ans ;
133
233
}
134
234
```
135
235
0 commit comments