class Solution {
public:
int racecar(int target) {
}
};
818. 赛车
你的赛车可以从位置0
开始,并且速度为 +1
,在一条无限长的数轴上行驶。赛车也可以向负方向行驶。赛车可以按照由加速指令 'A'
和倒车指令 'R'
组成的指令序列自动行驶。
'A'
时,赛车这样行驶:
position += speed
speed *= 2
'R'
时,赛车这样行驶:
speed = -1
speed = 1
例如,在执行指令 "AAR"
后,赛车位置变化为 0 --> 1 --> 3 --> 3
,速度变化为 1 --> 2 --> 4 --> -1
。
给你一个目标位置 target
,返回能到达目标位置的最短指令序列的长度。
示例 1:
输入:target = 3 输出:2 解释: 最短指令序列是 "AA" 。 位置变化 0 --> 1 --> 3 。
示例 2:
输入:target = 6 输出:5 解释: 最短指令序列是 "AAARA" 。 位置变化 0 --> 1 --> 3 --> 7 --> 7 --> 6 。
提示:
1 <= target <= 104
原站题解
golang 解法, 执行用时: 4 ms, 内存消耗: 2.2 MB, 提交时间: 2023-09-28 23:52:20
import "math" func racecar(target int) int { t := make([]int, target+1) for i := 1; i <= target; i++ { t[i] = math.MaxInt64 j, c := 1, 1 for ; j < i; j = (1 << uint(c)) - 1 { for k, c1 := 0, 0; k < j; k = (1 << uint(c1)) - 1 { t1 := c + c1 + 2 + t[i-j+k] if t1 < t[i] { t[i] = t1 } c1++ } c++ } t1 := c if i != j { t1 += 1 + t[j-i] } if t1 < t[i] { t[i] = t1 } } return t[target] }
java 解法, 执行用时: 7 ms, 内存消耗: 38 MB, 提交时间: 2023-09-28 23:51:34
class Solution { public int racecar(int target) { //处理边界 if (target <= 0) { return 0; } int[] dp = new int[target + 1]; Arrays.fill(dp, Integer.MAX_VALUE); for (int i = 1; i <= target; i++) { //先向前走 forward 步 for (int forward = 1; (1 << forward) - 1 < 2 * i; forward++) { //向前走了forwardDistance int forwardDistance = (1 << forward) - 1; //对应第一种情况,走了forward步直接到达i if (forwardDistance == i) { dp[i] = forward; } else if (forwardDistance > i) { //对应第二种情况,越过了i // +1 是因为回头需要一个R指令 dp[i] = Math.min(dp[i], forward + 1 + dp[forwardDistance - i]); } else { //对应第三种情况,没有越过i //先回头走backward步 for (int backward = 0; backward < forward; backward++) { int backwardDistance = (1 << backward) - 1; //第一个+1是还没到达i,先回头,使用一个R //第二个+1是回头走了backwardDistance,再使用R回头走向i dp[i] = Math.min(dp[i], forward + 1 + backward + 1 + dp[i - forwardDistance + backwardDistance]); } } } } return dp[target]; } }
java 解法, 执行用时: 4 ms, 内存消耗: 38.3 MB, 提交时间: 2023-09-28 23:44:30
class Solution { public int racecar(int target) { int[] dp = new int[target + 3]; Arrays.fill(dp, Integer.MAX_VALUE); dp[0] = 0; dp[1] = 1; dp[2] = 4; for (int t = 3; t <= target; ++t) { int k = 32 - Integer.numberOfLeadingZeros(t); if (t == (1<<k) - 1) { dp[t] = k; continue; } for (int j = 0; j < k-1; ++j) dp[t] = Math.min(dp[t], dp[t - (1<<(k-1)) + (1<<j)] + k-1 + j + 2); if ((1<<k) - 1 - t < t) dp[t] = Math.min(dp[t], dp[(1<<k) - 1 - t] + k + 1); } return dp[target]; } }
python3 解法, 执行用时: 292 ms, 内存消耗: 16.1 MB, 提交时间: 2023-09-28 23:44:14
class Solution: # dp[x] 表示到达位置 x 的最短指令长度 def racecar(self, target: int) -> int: dp = [0, 1, 4] + [float('inf')] * target for t in range(3, target + 1): k = t.bit_length() if t == 2**k - 1: dp[t] = k continue for j in range(k - 1): dp[t] = min(dp[t], dp[t - 2**(k - 1) + 2**j] + k - 1 + j + 2) if 2**k - 1 - t < t: dp[t] = min(dp[t], dp[2**k - 1 - t] + k + 1) return dp[target]
python3 解法, 执行用时: 920 ms, 内存消耗: 20 MB, 提交时间: 2023-09-28 23:42:31
class Solution: def racecar(self, target: int) -> int: K = target.bit_length() + 1 barrier = 1 << K pq = [(0, target)] dist = [float('inf')] * (2 * barrier + 1) dist[target] = 0 while pq: steps, targ = heapq.heappop(pq) if dist[targ] > steps: continue for k in range(K+1): walk = (1 << k) - 1 steps2, targ2 = steps + k + 1, walk - targ if walk == targ: steps2 -= 1 #No "R" command if already exact if abs(targ2) <= barrier and steps2 < dist[targ2]: heapq.heappush(pq, (steps2, targ2)) dist[targ2] = steps2 return dist[0]
java 解法, 执行用时: 82 ms, 内存消耗: 43 MB, 提交时间: 2023-09-28 23:42:01
// Djikstra class Solution { public int racecar(int target) { int K = 33 - Integer.numberOfLeadingZeros(target - 1); int barrier = 1 << K; int[] dist = new int[2 * barrier + 1]; Arrays.fill(dist, Integer.MAX_VALUE); dist[target] = 0; PriorityQueue<Node> pq = new PriorityQueue<Node>( (a, b) -> a.steps - b.steps); pq.offer(new Node(0, target)); while (!pq.isEmpty()) { Node node = pq.poll(); int steps = node.steps, targ1 = node.target; if (dist[Math.floorMod(targ1, dist.length)] > steps) continue; for (int k = 0; k <= K; ++k) { int walk = (1 << k) - 1; int targ2 = walk - targ1; int steps2 = steps + k + (targ2 != 0 ? 1 : 0); if (Math.abs(targ2) <= barrier && steps2 < dist[Math.floorMod(targ2, dist.length)]) { pq.offer(new Node(steps2, targ2)); dist[Math.floorMod(targ2, dist.length)] = steps2; } } } return dist[0]; } } class Node { int steps, target; Node(int s, int t) { steps = s; target = t; } }