【线性 dp】A002_LC_跳跃游戏 V(记忆化搜索 / 排序 + dp + 疑惑)

一、Problem

Given an array of integers arr and an integer d. In one step you can jump from index i to index:

i + x where: i + x < arr.length and 0 < x <= d.
i - x where: i - x >= 0 and 0 < x <= d.
In addition, you can only jump from index i to index j if arr[i] > arr[j] and arr[i] > arr[k] for all indices k between i and j (More formally min(i, j) < k < max(i, j)).

You can choose any index of the array and start jumping. Return the maximum number of indices you can visit.

Notice that you can not jump outside of the array at any time.
在这里插入图片描述

Input: arr = [6,4,14,6,8,13,9,7,10,6,12], d = 2
Output: 4
Explanation: You can start at index 10. You can jump 10 --> 8 --> 6 --> 7 as shown.
Note that if you start at index 6 you can only jump to index 7. 
You cannot jump to index 5 because 13 > 9. 
You cannot jump to index 4 because index 5 is between index 4 and 6 and 13 > 9.
Similarly You cannot jump from index 3 to index 2 or index 1.

二、Solution

方法一:记忆化搜索

  • 题目中说道可以从任意一个位置 ii 开始跳跃,说明我们不能只枚举一个点
  • 而且从某一个位置可以向左也可以向右跳区间 [d,d][-d, d] 范围内的距离。
  • 只能跳到两侧比自己矮的柱子。
class Solution {
    int d, n, A[], dp[];
    int dfs(int x) {
        if (dp[x] != 0)
            return dp[x];
        int tt = 1;
        for (int y = x-1; y >= 0 && x - y <= d && A[y] < A[x]; y--) {
            tt = Math.max(tt, dfs(y) + 1);
        }
        for (int y = x+1; y < n && y - x <= d && A[y] < A[x]; y++) {
            tt = Math.max(tt, dfs(y) + 1);
        }
        return dp[x] = tt;
    }
    public int maxJumps(int[] A, int d) {
        this.d = d;
        this.A = A;
        n = A.length;
        dp = new int[n];
        int max = 0;
        for (int i = 0; i < n; i++) {
            max = Math.max(max, dfs(i));
        }
        return max;
    }
}

复杂度分析

  • 时间复杂度:O(d×n)O(d × n),dfs 中至多执行 d 层循环
  • 空间复杂度:O(n)O(n)

方法二:排序 + dp

  • 定义状态
    • dp[i]dp[i] 表示 ii 位置的格子的最多可到达数。
  • 思考初始化:
    • dp[i]=1dp[i] = 1
  • 思考状态转移方程
    • 对于区间 j[0,i)j∈[0, i)dp[i]=max(dp[j])+1dp[i] = max(dp[j]) + 1
    • 对于区间 j[i+1,n)j∈[i+1, n)dp[i]=max(dp[j])+1dp[i] = max(dp[j]) + 1
  • 思考输出max(dp[0...i])max(dp[0...i])

不是很懂为什么要排序…


复杂度分析

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