48
48
49
49
** 方法一:两次遍历**
50
50
51
- 两次遍历,找出每个字符左侧和右侧最近的 c,算出最短距离 。
51
+ 我们先创建一个长度为 $n$ 的答案数组 $ans$ 。
52
52
53
- ** 方法二:BFS **
53
+ 接下来,我们从左到右遍历字符串 $s$,记录最近出现的字符 $c$ 的位置 $pre$,那么对于位置 $i$,答案就是 $i - pre$,即 $ans [ i ] = i - pre$。
54
54
55
- 在字符串 s 中找出所有字符 c 对应的下标,并放入队列 q 。
55
+ 然后,我们从右到左遍历字符串 $s$,记录最近出现的字符 $c$ 的位置 $suf$,那么对于位置 $i$,答案就是 $suf - i$,即 $ans [ i ] = \min(ans [ i ] , suf - i)$ 。
56
56
57
- BFS 向左右两边扩散,找出最短距离。
57
+ 最后返回答案数组 $ans$ 即可。
58
+
59
+ 时间复杂度 $O(n)$,其中 $n$ 是字符串 $s$ 的长度。忽略答案数组的空间消耗,空间复杂度 $O(1)$。
58
60
59
61
<!-- tabs:start -->
60
62
@@ -66,34 +68,17 @@ BFS 向左右两边扩散,找出最短距离。
66
68
class Solution :
67
69
def shortestToChar (self , s : str , c : str ) -> List[int ]:
68
70
n = len (s)
69
- ans = [0 ] * n
70
- j = inf
71
+ ans = [n ] * n
72
+ pre = - inf
71
73
for i, ch in enumerate (s):
72
74
if ch == c:
73
- j = i
74
- ans[i] = abs (i - j )
75
- j = inf
75
+ pre = i
76
+ ans[i] = min (ans[i], i - pre )
77
+ suf = inf
76
78
for i in range (n - 1 , - 1 , - 1 ):
77
79
if s[i] == c:
78
- j = i
79
- ans[i] = min (ans[i], abs (i - j))
80
- return ans
81
- ```
82
-
83
- ``` python
84
- class Solution :
85
- def shortestToChar (self , s : str , c : str ) -> List[int ]:
86
- q = deque([i for i, ch in enumerate (s) if ch == c])
87
- ans = [0 if ch == c else - 1 for ch in s]
88
- d = 0
89
- while q:
90
- d += 1
91
- for _ in range (len (q)):
92
- i = q.popleft()
93
- for j in (i - 1 , i + 1 ):
94
- if 0 <= j < len (s) and ans[j] == - 1 :
95
- ans[j] = d
96
- q.append(j)
80
+ suf = i
81
+ ans[i] = min (ans[i], suf - i)
97
82
return ans
98
83
```
99
84
@@ -106,94 +91,103 @@ class Solution {
106
91
public int [] shortestToChar (String s , char c ) {
107
92
int n = s. length();
108
93
int [] ans = new int [n];
109
- for (int i = 0 , j = Integer . MAX_VALUE ; i < n; ++ i) {
94
+ final int inf = 1 << 30 ;
95
+ Arrays . fill(ans, inf);
96
+ for (int i = 0 , pre = - inf; i < n; ++ i) {
110
97
if (s. charAt(i) == c) {
111
- j = i;
98
+ pre = i;
112
99
}
113
- ans[i] = Math . abs(i - j );
100
+ ans[i] = Math . min(ans[i], i - pre );
114
101
}
115
- for (int i = n - 1 , j = Integer . MAX_VALUE ; i >= 0 ; -- i) {
102
+ for (int i = n - 1 , suf = inf ; i >= 0 ; -- i) {
116
103
if (s. charAt(i) == c) {
117
- j = i;
104
+ suf = i;
118
105
}
119
- ans[i] = Math . min(ans[i], Math . abs(i - j) );
106
+ ans[i] = Math . min(ans[i], suf - i );
120
107
}
121
108
return ans;
122
109
}
123
110
}
124
111
```
125
112
126
- ``` java
113
+ ### ** C++**
114
+
115
+ ``` cpp
127
116
class Solution {
128
- public int [] shortestToChar (String s , char c ) {
129
- Deque<Integer > q = new ArrayDeque<> ();
130
- int n = s. length();
131
- int [] ans = new int [n];
132
- Arrays . fill(ans, - 1 );
133
- for (int i = 0 ; i < n; ++ i) {
134
- if (s. charAt(i) == c) {
135
- q. offer(i);
136
- ans[i] = 0 ;
117
+ public:
118
+ vector<int > shortestToChar(string s, char c) {
119
+ int n = s.size();
120
+ const int inf = 1 << 30;
121
+ vector<int > ans(n, inf);
122
+ for (int i = 0, pre = -inf; i < n; ++i) {
123
+ if (s[ i] == c) {
124
+ pre = i;
137
125
}
126
+ ans[ i] = min(ans[ i] , i - pre);
138
127
}
139
- int d = 0 ;
140
- while (! q. isEmpty()) {
141
- ++ d;
142
- for (int t = q. size(); t > 0 ; -- t) {
143
- int i = q. poll();
144
- for (int j : Arrays . asList(i - 1 , i + 1 )) {
145
- if (j >= 0 && j < n && ans[j] == - 1 ) {
146
- ans[j] = d;
147
- q. offer(j);
148
- }
149
- }
128
+ for (int i = n - 1, suf = inf; ~ i; --i) {
129
+ if (s[ i] == c) {
130
+ suf = i;
150
131
}
132
+ ans[ i] = min(ans[ i] , suf - i);
151
133
}
152
134
return ans;
153
135
}
154
- }
136
+ };
155
137
```
156
138
157
- ### ** TypeScript **
139
+ ### **Go **
158
140
159
- ``` ts
160
- function shortestToChar(s : string , c : string ): number [] {
161
- const n = s .length ;
162
- let ans = [];
163
- let pre = Infinity ;
164
- for (let i = 0 ; i < n ; i ++ ) {
165
- if (s .charAt (i ) == c ) pre = i ;
166
- ans [i ] = Math .abs (pre - i );
167
- }
168
- pre = Infinity ;
169
- for (let i = n - 1 ; i > - 1 ; i -- ) {
170
- if (s .charAt (i ) == c ) pre = i ;
171
- ans [i ] = Math .min (Math .abs (pre - i ), ans [i ]);
172
- }
173
- return ans ;
141
+ ```go
142
+ func shortestToChar(s string, c byte) []int {
143
+ n := len(s)
144
+ ans := make([]int, n)
145
+ const inf int = 1 << 30
146
+ pre := -inf
147
+ for i := range s {
148
+ if s[i] == c {
149
+ pre = i
150
+ }
151
+ ans[i] = i - pre
152
+ }
153
+ suf := inf
154
+ for i := n - 1; i >= 0; i-- {
155
+ if s[i] == c {
156
+ suf = i
157
+ }
158
+ ans[i] = min(ans[i], suf-i)
159
+ }
160
+ return ans
161
+ }
162
+
163
+ func min(a, b int) int {
164
+ if a < b {
165
+ return a
166
+ }
167
+ return b
174
168
}
175
169
```
176
170
171
+ ### ** TypeScript**
172
+
177
173
``` ts
178
174
function shortestToChar(s : string , c : string ): number [] {
179
175
const n = s .length ;
180
- const idxs = [];
181
- for (let i = 0 ; i < n ; i ++ ) {
176
+ const inf = 1 << 30 ;
177
+ const ans: number [] = new Array (n ).fill (inf );
178
+ for (let i = 0 , pre = - inf ; i < n ; ++ i ) {
182
179
if (s [i ] === c ) {
183
- idxs . push ( i ) ;
180
+ pre = i ;
184
181
}
182
+ ans [i ] = i - pre ;
185
183
}
186
- idxs .push (Infinity );
187
-
188
- const res = new Array (n );
189
- let i = 0 ;
190
- for (let j = 0 ; j < n ; j ++ ) {
191
- if (Math .abs (idxs [i ] - j ) > Math .abs (idxs [i + 1 ] - j )) {
192
- i ++ ;
184
+ for (let i = n - 1 , suf = inf ; i >= 0 ; -- i ) {
185
+ if (s [i ] === c ) {
186
+ suf = i ;
193
187
}
194
- res [ j ] = Math .abs ( idxs [i ] - j );
188
+ ans [ i ] = Math .min ( ans [i ], suf - i );
195
189
}
196
- return res ;
190
+ return ans ;
197
191
}
198
192
```
199
193
@@ -225,115 +219,6 @@ impl Solution {
225
219
}
226
220
```
227
221
228
- ### ** C++**
229
-
230
- ``` cpp
231
- class Solution {
232
- public:
233
- vector<int > shortestToChar(string s, char c) {
234
- int n = s.size();
235
- vector<int > ans(n);
236
- for (int i = 0, j = INT_MAX; i < n; ++i) {
237
- if (s[ i] == c) j = i;
238
- ans[ i] = abs(i - j);
239
- }
240
- for (int i = n - 1, j = INT_MAX; i >= 0; --i) {
241
- if (s[ i] == c) j = i;
242
- ans[ i] = min(ans[ i] , abs(i - j));
243
- }
244
- return ans;
245
- }
246
- };
247
- ```
248
-
249
- ```cpp
250
- class Solution {
251
- public:
252
- vector<int> shortestToChar(string s, char c) {
253
- int n = s.size();
254
- vector<int> ans(n, -1);
255
- queue<int> q;
256
- for (int i = 0; i < n; ++i) {
257
- if (s[i] == c) {
258
- q.push(i);
259
- ans[i] = 0;
260
- }
261
- }
262
- int d = 0;
263
- while (!q.empty()) {
264
- ++d;
265
- for (int t = q.size(); t > 0; --t) {
266
- int i = q.front();
267
- q.pop();
268
- vector<int> dirs{i - 1, i + 1};
269
- for (int& j : dirs) {
270
- if (j >= 0 && j < n && ans[j] == -1) {
271
- ans[j] = d;
272
- q.push(j);
273
- }
274
- }
275
- }
276
- }
277
- return ans;
278
- }
279
- };
280
- ```
281
-
282
- ### ** Go**
283
-
284
- ``` go
285
- func shortestToChar (s string , c byte ) []int {
286
- n := len (s)
287
- ans := make ([]int , n)
288
- for i , j := 0 , -10000 ; i < n; i++ {
289
- if s[i] == c {
290
- j = i
291
- }
292
- ans[i] = i - j
293
- }
294
- for i , j := n-1 , 10000 ; i >= 0 ; i-- {
295
- if s[i] == c {
296
- j = i
297
- }
298
- if j-i < ans[i] {
299
- ans[i] = j - i
300
- }
301
- }
302
- return ans
303
- }
304
- ```
305
-
306
- ``` go
307
- func shortestToChar (s string , c byte ) []int {
308
- n := len (s)
309
- var q []int
310
- ans := make ([]int , n)
311
- for i := range s {
312
- ans[i] = -1
313
- if s[i] == c {
314
- q = append (q, i)
315
- ans[i] = 0
316
- }
317
- }
318
-
319
- d := 0
320
- for len (q) > 0 {
321
- d++
322
- for t := len (q); t > 0 ; t-- {
323
- i := q[0 ]
324
- q = q[1 :]
325
- for _ , j := range []int {i - 1 , i + 1 } {
326
- if j >= 0 && j < n && ans[j] == -1 {
327
- ans[j] = d
328
- q = append (q, j)
329
- }
330
- }
331
- }
332
- }
333
- return ans
334
- }
335
- ```
336
-
337
222
### ** ...**
338
223
339
224
```
0 commit comments