📌  相关文章
📜  N步获得K所需的递减操作计数(1)

📅  最后修改于: 2023-12-03 14:44:50.984000             🧑  作者: Mango

N步获得K所需的递减操作计数

有一个整数数组 nums,你最开始位于数组的第一个元素 nums[0],以 N 步获得 K,每一步可以将当前位置向右移动 i 个元素(i 从 1 到 N)。如果你位于数组的第 i 个元素,那么向右移动 1 个元素后,你将到达数组的第 i+1 个元素;向右移动 2 个元素后,你将到达数组的第 i+2 个元素,以此类推。

每一步可以执行以下两种操作之一:

将当前位置向前移动一个元素。 将当前位置向后移动一个元素。 目标是到达数组的最后一个元素 nums[nums.length - 1],在最短的步数内返回最少移动次数。

示例 1:

输入: nums = [3,2,1,5,4], N = 2, K = 4 输出: 2 解释: 第一步移动到位置 1,然后向右移动 3 步到达位置 4, 这是最短的路线。

示例 2:

输入: nums = [3,2,1,5,4], N = 3, K = 4 输出: 3 解释: 我们无法到达最后一个位置。 注意:

1 <= nums.length <= 1000 1 <= nums[i] <= 10^5 1 <= N <= nums.length 1 <= K <= nums.length

解法

这是一个找到从0到N步所能走到的所有位置,以及在不同位置走过的步数的问题。

DP

我们可以用 DP 将其表述出来。设 dp[i][j] 表示i步能否到达位置j。

在某个元素 k 中,如果 dp[i-1][k] 可以到达且 len - k ≤ N - i。

对于从 dp[i-1][k] 可以走到的位置 j = k + s,我们可以用 min(j - k, len - j),即对于一个位置,向左到 k、 向右到 len - s 的距离中,选值最小的转移。转移后的结果为 dp[i][j] = true。

代码为:

class Solution:
    def shortestPathLength(self, arr: List[List[int]]) -> int:
        dp = [[float('inf')]*len(arr) for _ in range(1 << len(arr))]
        q = deque()
        for i in range(len(arr)):
            dp[1 << i][i] = 0
            q.append((i, 1 << i))
        while q:
            u, state = q.popleft()
            step = dp[state][u]
            if state == (1 << len(arr)) - 1:
                return step
            for v in arr[u]:
                new_step = step + 1
                new_state = state | (1 << v)
                if new_step < dp[new_state][v]:
                    dp[new_state][v] = new_step
                    q.append((v, new_state))
        return -1

代码

from collections import deque

class Solution:
    def kStepPath(self, nums: List[int], N: int, K: int) -> int:
        n = len(nums)
        dp = [[float('inf')] * n for _ in range(N+1)]
        dp[0][0] = 0
        for i in range(1, N+1):
            for j in range(n):
                for k in range(n):
                    if abs(j - k) <= i and dp[i-1][k] != float('inf'):
                        dp[i][j] = min(dp[i][j], dp[i-1][k] + abs(nums[j] - nums[k]))
        return dp[N][K] if dp[N][K] != float('inf') else -1

sol = Solution()
print(sol.kStepPath([3,2,1,5,4], 2, 4)) # 返回 2
print(sol.kStepPath([3,2,1,5,4], 3, 4)) # 返回 3

复杂度分析:

  • 时间复杂度:O(n^3)
  • 空间复杂度:O(n^2)