@@ -107,32 +107,291 @@ tags:
107107
108108<!-- solution:start -->
109109
110- ### 方法一
110+ ### 方法一:预处理 + BFS
111+
112+ 我们首先预处理出 $10^6$ 内的每个数的质因数列表,记录在 $\textit{factors}$ 中。
113+
114+ 然后我们构建一个图 $g$,对于每个下标 $i$ 和 $p \in \textit{factors}[ nums[ i]] $,我们将 $i$ 加入 $g[ p] $ 中。这样我们就得到了每个质数 $p$ 可以传送到的下标列表。
115+
116+ 接下来我们使用广度优先搜索来求解最少跳跃次数。我们维护一个队列 $q$ 来存储当前可以跳跃到的下标,初始时 $q$ 中只有下标 $0$。每次从 $q$ 中取出一个下标 $i$,如果 $i$ 是目标下标 $n - 1$,则返回当前跳跃次数;否则,我们将 $g[ nums[ i]] $ 中的所有下标加入 $q$ 中,并将它们从 $g[ nums[ i]] $ 中移除,以避免重复访问;同时,我们还将相邻的下标 $i + 1$ 和 $i - 1$(如果在边界内)加入 $q$ 中。
117+
118+ 时间复杂度 $O(n \log M)$,空间复杂度 $O(n \log M)$,其中 $n$ 是数组的长度,而 $M$ 是数组中元素的最大值。
111119
112120<!-- tabs:start -->
113121
114122#### Python3
115123
116124``` python
117-
125+ mx = 10 ** 6 + 1
126+ factors = [[] for _ in range (mx)]
127+ for i in range (2 , mx):
128+ if not factors[i]:
129+ for j in range (i, mx, i):
130+ factors[j].append(i)
131+
132+
133+ class Solution :
134+ def minJumps (self , nums : List[int ]) -> int :
135+ n = len (nums)
136+ g = defaultdict(list )
137+ for i, x in enumerate (nums):
138+ for p in factors[x]:
139+ g[p].append(i)
140+ ans = 0
141+ vis = [False ] * n
142+ vis[0 ] = True
143+ q = [0 ]
144+ while 1 :
145+ nq = []
146+ for i in q:
147+ if i == n - 1 :
148+ return ans
149+ idx = g[nums[i]]
150+ idx.append(i + 1 )
151+ if i:
152+ idx.append(i - 1 )
153+ for j in idx:
154+ if not vis[j]:
155+ vis[j] = True
156+ nq.append(j)
157+ idx.clear()
158+ q = nq
159+ ans += 1
118160```
119161
120162#### Java
121163
122164``` java
123-
165+ class Solution {
166+ private static final int mx = 1000001 ;
167+ private static final List<Integer > [] factors = new List [mx];
168+
169+ static {
170+ for (int i = 0 ; i < mx; i++ ) {
171+ factors[i] = new ArrayList<> ();
172+ }
173+ for (int i = 2 ; i < mx; i++ ) {
174+ if (factors[i]. isEmpty()) {
175+ for (int j = i; j < mx; j += i) {
176+ factors[j]. add(i);
177+ }
178+ }
179+ }
180+ }
181+
182+ public int minJumps (int [] nums ) {
183+ int n = nums. length;
184+ Map<Integer , List<Integer > > g = new HashMap<> ();
185+ for (int i = 0 ; i < n; i++ ) {
186+ int x = nums[i];
187+ for (int p : factors[x]) {
188+ g. computeIfAbsent(p, k - > new ArrayList<> ()). add(i);
189+ }
190+ }
191+ int ans = 0 ;
192+ boolean [] vis = new boolean [n];
193+ vis[0 ] = true ;
194+ Deque<Integer > q = new ArrayDeque<> ();
195+ q. offer(0 );
196+ while (true ) {
197+ Deque<Integer > nq = new ArrayDeque<> ();
198+ for (int i : q) {
199+ if (i == n - 1 ) {
200+ return ans;
201+ }
202+ List<Integer > idx = g. getOrDefault(nums[i], new ArrayList<> ());
203+ idx. add(i + 1 );
204+ if (i > 0 ) {
205+ idx. add(i - 1 );
206+ }
207+ for (int j : idx) {
208+ if (! vis[j]) {
209+ vis[j] = true ;
210+ nq. offer(j);
211+ }
212+ }
213+ idx. clear();
214+ }
215+ q = nq;
216+ ans++ ;
217+ }
218+ }
219+ }
124220```
125221
126222#### C++
127223
128224``` cpp
129-
225+ const int mx = 1e6 + 1 ;
226+ vector<int > factors[mx];
227+
228+ int init = [] {
229+ for (int i = 2; i < mx; ++i) {
230+ if (factors[i].empty()) {
231+ for (int j = i; j < mx; j += i) {
232+ factors[j].push_back(i);
233+ }
234+ }
235+ }
236+ return 0;
237+ }();
238+
239+ class Solution {
240+ public:
241+ int minJumps(vector<int >& nums) {
242+ int n = nums.size();
243+ unordered_map<int, vector<int >> g;
244+ for (int i = 0; i < n; i++) {
245+ int x = nums[ i] ;
246+ for (int p : factors[ x] ) {
247+ g[ p] .push_back(i);
248+ }
249+ }
250+ int ans = 0;
251+ vector<bool > vis(n, false);
252+ vis[ 0] = true;
253+ queue<int > q;
254+ q.push(0);
255+ while (true) {
256+ queue<int > nq;
257+ while (!q.empty()) {
258+ int i = q.front();
259+ q.pop();
260+ if (i == n - 1) {
261+ return ans;
262+ }
263+ vector<int > idx = g[ nums[ i]] ;
264+ idx.push_back(i + 1);
265+ if (i > 0) {
266+ idx.push_back(i - 1);
267+ }
268+ for (int j : idx) {
269+ if (!vis[ j] ) {
270+ vis[ j] = true;
271+ nq.push(j);
272+ }
273+ }
274+ g[ nums[ i]] .clear();
275+ }
276+ q = nq;
277+ ans++;
278+ }
279+ }
280+ };
130281```
131282
132283#### Go
133284
134285```go
286+ const mx = 1000001
287+
288+ var factors [mx][]int
289+
290+ func init() {
291+ for i := 2; i < mx; i++ {
292+ if len(factors[i]) == 0 {
293+ for j := i; j < mx; j += i {
294+ factors[j] = append(factors[j], i)
295+ }
296+ }
297+ }
298+ }
299+
300+ func minJumps(nums []int) int {
301+ n := len(nums)
302+ g := make(map[int][]int)
303+ for i, x := range nums {
304+ for _, p := range factors[x] {
305+ g[p] = append(g[p], i)
306+ }
307+ }
308+ ans := 0
309+ vis := make([]bool, n)
310+ vis[0] = true
311+ q := []int{0}
312+ for {
313+ nq := []int{}
314+ for _, i := range q {
315+ if i == n-1 {
316+ return ans
317+ }
318+ idx := append([]int{}, g[nums[i]]...)
319+ idx = append(idx, i+1)
320+ if i > 0 {
321+ idx = append(idx, i-1)
322+ }
323+ for _, j := range idx {
324+ if !vis[j] {
325+ vis[j] = true
326+ nq = append(nq, j)
327+ }
328+ }
329+ g[nums[i]] = []int{}
330+ }
331+ q = nq
332+ ans++
333+ }
334+ }
335+ ```
135336
337+ #### TypeScript
338+
339+ ``` ts
340+ const mx = 1000001 ;
341+ const factors: number [][] = Array (mx );
342+
343+ for (let i = 0 ; i < mx ; i ++ ) {
344+ factors [i ] = [];
345+ }
346+ for (let i = 2 ; i < mx ; i ++ ) {
347+ if (factors [i ].length === 0 ) {
348+ for (let j = i ; j < mx ; j += i ) {
349+ factors [j ].push (i );
350+ }
351+ }
352+ }
353+
354+ function minJumps(nums : number []): number {
355+ const n = nums .length ;
356+ const g = new Map <number , number []>();
357+ for (let i = 0 ; i < n ; i ++ ) {
358+ const x = nums [i ];
359+ for (const p of factors [x ]) {
360+ if (! g .has (p )) {
361+ g .set (p , []);
362+ }
363+ g .get (p )! .push (i );
364+ }
365+ }
366+ let ans = 0 ;
367+ const vis = new Array (n ).fill (false );
368+ vis [0 ] = true ;
369+ let q: number [] = [0 ];
370+ while (true ) {
371+ const nq: number [] = [];
372+ for (const i of q ) {
373+ if (i === n - 1 ) {
374+ return ans ;
375+ }
376+ const idx = [... (g .get (nums [i ]) || [])];
377+ idx .push (i + 1 );
378+ if (i > 0 ) {
379+ idx .push (i - 1 );
380+ }
381+ for (const j of idx ) {
382+ if (! vis [j ]) {
383+ vis [j ] = true ;
384+ nq .push (j );
385+ }
386+ }
387+ if (g .has (nums [i ])) {
388+ g .get (nums [i ])! .length = 0 ;
389+ }
390+ }
391+ q = nq ;
392+ ans ++ ;
393+ }
394+ }
136395```
137396
138397<!-- tabs: end -->
0 commit comments