【搜索】A056_LC_跳躍遊戲 IV(一維 bfs / 雙向 bfs)

一、Problem

Given an array of integers arr, you are initially positioned at the first index of the array.

In one step you can jump from index i to index:

  • i + 1 where: i + 1 < arr.length.
  • i - 1 where: i - 1 >= 0.
  • j where: arr[i] == arr[j] and i != j.

Return the minimum number of steps to reach the last index of the array.

Notice that you can not jump outside of the array at any time.

Input: arr = [100,-23,-23,404,100,23,23,23,3,404]
Output: 3
Explanation: You need three jumps from index 0 --> 4 --> 3 --> 9. Note that index 9 is the last index of the array.

二、Solution

方法一:bfs

Q&A:

  • Q1:爲什麼不是 dp?
    A1:因爲同一個位置可能存在多次跳躍,也就是說,已經後面跳過的位置會影響前面跳過的位置,不符合 dp 的無後效性。
class Solution {
	int n, A[];
	Map<Integer, List<Integer>> mp;
	int bfs(int S) {
		Queue<Integer> q = new ArrayDeque<>();
		q.add(S);
		boolean[] vis = new boolean[n];
		int s = 0;
		vis[S] = true;
		while (!q.isEmpty()) {
			int sz = q.size();
			for (int i = 0; i < sz; i++) {
                int cur = q.poll();
				if (cur == n-1) 
					return s;
				if (cur + 1 < n && !vis[cur+1]) {
					q.add(cur+1);
					vis[cur+1] = true;
				}if (cur - 1 >= 0 && !vis[cur-1]) {
					q.add(cur-1);
					vis[cur-1] = true;
				}for (int idx : mp.get(A[cur])) {
					if (!vis[idx]) {
						q.add(idx);
						vis[idx] = true;
					}
				}
			}
			s++;
		}
		return 0;
	}
    public int minJumps(int[] A) {
		n = A.length;
		this.A = A;
		mp = new HashMap<>();
		for (int i = 0; i < n; i++) {
			mp.computeIfAbsent(A[i], k -> new ArrayList<>()).add(i);
		}
		return bfs(0);
    }
}

Q2:爲什麼下面的程序會超時,加了記錄數組了呀?
A2:觀察到有一個很長的都是相同元素的輸入,又由於 bfs 第一次到達一個位置一定是花費最少,所以再次跳到相同的元素的位置是沒有意義的,而每次都對取 for 遍歷這些相同元素會造成時間浪費。

class Solution {
	int n, A[];
	Map<Integer, List<Integer>> mp;
	int bfs(int S) {
		Queue<Integer> q = new ArrayDeque<>();
		q.add(S);
		boolean[] vis = new boolean[n];
		int s = 0;
		vis[S] = true;
		while (!q.isEmpty()) {
			int sz = q.size();
			for (int i = 0; i < sz; i++) {
                int cur = q.poll();
				if (cur == n-1) 
					return s;
                if (mp.get(A[cur]) != null)
                for (int idx : mp.get(A[cur])) {
					if (!vis[idx]) {
						q.add(idx);
						vis[idx] = true;
					}
				}
                mp.remove(A[cur]);
				if (cur + 1 < n && !vis[cur+1]) {
					q.add(cur+1);
					vis[cur+1] = true;
				}if (cur - 1 >= 0 && !vis[cur-1]) {
					q.add(cur-1);
					vis[cur-1] = true;
				}
			}
			s++;
		}
		return 0;
	}
    public int minJumps(int[] A) {
		n = A.length;
		this.A = A;
		mp = new HashMap<>();
		for (int i = 0; i < n; i++) {
			mp.computeIfAbsent(A[i], k -> new ArrayList<>()).add(i);
		}
		return bfs(0);
    }
}

複雜度分析

  • 時間複雜度:O(n)O(n)
  • 空間複雜度:O(n)O(n)

方法二:雙向 bfs

代辦…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章