Skip to content

Commit 3b86a94

Browse files
committed
feat: add solutions to lc problem: No.1182
No.1182. Shortest Distance to Target Color
1 parent 6e8fe51 commit 3b86a94

File tree

7 files changed

+437
-160
lines changed

7 files changed

+437
-160
lines changed

solution/1100-1199/1182.Shortest Distance to Target Color/README.md

Lines changed: 154 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,13 @@
5050

5151
<!-- 这里可写通用的实现逻辑 -->
5252

53-
二分查找。
53+
**方法一:预处理**
5454

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$ 的长度。
5660

5761
<!-- tabs:start -->
5862

@@ -62,32 +66,23 @@
6266

6367
```python
6468
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 = []
7282
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
9186
```
9287

9388
### **Java**
@@ -97,39 +92,144 @@ class Solution:
9792
```java
9893
class Solution {
9994
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];
111102
}
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];
121110
}
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];
125137
}
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];
128145
}
129-
res.add(val);
146+
left[i][colors[i - 1] - 1] = i - 1;
130147
}
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);
132231
}
232+
return ans;
133233
}
134234
```
135235

0 commit comments

Comments
 (0)