【贪心】A034_LC_跳跃游戏 II(暴搜 / dp / bfs)

一、Problem

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Your goal is to reach the last index in the minimum number of jumps.

Input: [2,3,1,1,4]
Output: 2
Explanation: The minimum number of jumps to reach the last index is 2.
    Jump 1 step from index 0 to 1, then 3 steps to the last index.

Note:

You can assume that you can always reach the last index.

二、Solution

方法一:暴搜

枚举每一种跳法,看是否能到达终点或终点之后。

71 / 92 超时啦…

class Solution {
	int N, A[], step = 0x3f3f3f3f;
	void dfs(int idx, int stp) {
		if (idx >= N-1) {
			step = Math.min(step, stp);
			return;
		}
		for (int i = 1; i <= A[idx]; i++) {
			dfs(idx+i, stp+1);
		}
	}
    public int jump(int[] nums) {
		N = nums.length;
		A = nums;
		dfs(0, 0);
		return step;
    }
}

复杂度分析

  • 时间复杂度:O(2N)O(2^N),N 为 0NA[i]\sum_{0}^{N} A[i]
  • 空间复杂度:O(n)O(n)

方法二:dp

  • 定义状态
    • dp[i]dp[i] 表示跳到第 i 个位置需要的最少步数。
  • 思考状态转移方程
    • 如果满足 A[j]+j>=A[i]A[j] + j >= A[i],则有 dp[i]=Math.min(dp[i],dp[j]+1)dp[i] = Math.min(dp[i], dp[j] + 1),即表示如果在 j 位置能一步到达 i 位置,证明从 j 到达 i 的最少步数一定是 1 了
  • 思考初始化:
    • dp[0]=0dp[0] = 0
  • 思考输出dp[N1]dp[N-1]

加了个剪枝,勉强过吧…

class Solution {
    public int jump(int[] A) {
		int N = A.length, dp[] = new int[N];
		Arrays.fill(dp, 0x3f3f3f3f);
		dp[0] = 0;
		for (int r = 1; r < N; r++)
		for (int l = 0; l < N; l++) {
			if (A[l] + l >= r) {
				dp[r] = Math.min(dp[r], dp[l]+1);
				break;
			}
		}
		return dp[N-1];
    }
}

复杂度分析

  • 时间复杂度:O(n2)O(n^2),最坏是 O(n2)O(n^2)
  • 空间复杂度:O(n)O(n)

方法三:bfs

  • 和 dfs 大同小异,有一点不同的就是:bfs 每次都是尝试走大步,即 for (int i = A[id]; i >= 0; i--) {,而第一次到达是最小步数。
  • dfs 不同,是枚举了所有到达的可能,取最小…
class Solution {
    public int jump(int[] A) {
		int N = A.length;
        if (N == 1)
            return 0;
		Queue<Pos> q = new ArrayDeque<>();
		q.add(new Pos(0, 0));
		boolean[] vis = new boolean[N];
		vis[0] = true;
		while (!q.isEmpty()) {
			int id = q.peek().id, step = q.peek().step; q.poll();
			for (int i = A[id]; i >= 0; i--) {
				if (id + i >= N-1)
					return step + 1;
				if (!vis[id+i]) {
					q.add(new Pos(id+i, step+1));
					vis[id+i] = true;
				}
			}
		}
		return -1;
    }
	class Pos {
		int id, step;
		Pos(int id, int step) {this.id = id;this.step = step;}
	}
}

复杂度分析

  • 时间复杂度:O(n2)O(n^2),最坏是 O(n2)O(n^2)
  • 空间复杂度:O(n)O(n)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章