📅  最后修改于: 2023-12-03 14:44:50.984000             🧑  作者: Mango
有一个整数数组 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[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
复杂度分析: