class Solution {
public:
int minSideJumps(vector<int> &ob) {
int len = ob.size();
int res = 0;
int num = 2;
for (int i = 0; i < len; i++) {
if (ob[i + 1] == num) {
set<int> choice = {1, 2, 3};
choice.erase(num);
choice.erase(ob[i]);
if (choice.size() == 1) {
num = *choice.begin();
res++;
} else {
map<int, int> cntLen;
int a[6], t = 0;
for (auto &e: choice) {
int tmp = i;
while (tmp < len && ob[tmp] != e) tmp++;
cntLen[tmp] = e;
a[t++] = tmp;
}
num = cntLen[max(a[0], a[1])];
res++;
}
}
}
return res;
}
};
DP
本来是 dp[i][1…3]
i表示当前位置,3表示三个赛道
dp[i][j] 表示到达第i个位置的第j个赛道,需要跳跃的最小次数
状态转移:
d
p
[
i
]
[
j
]
=
m
i
n
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
−
1
]
[
j
2
]
+
1
,
d
p
[
i
−
1
]
[
j
3
+
1
]
dp[i][j] = min(dp[i-1][j], dp[i-1][j_2] + 1, dp[i-1][j_3 + 1]
dp[i][j]=min(dp[i−1][j],dp[i−1][j2]+1,dp[i−1][j3+1]
后来发现 dp[i][j] 仅仅和 dp[i -1][j] 有关,因此可以只用一维数组来做
时间复杂度
O
(
n
)
O(n)
O(n)
class Solution {
public:
int minSideJumps(vector<int> &ob) {
int len = ob.size();
int dp[4];
fill(dp, dp + 4, 1);
// cout << dp[1] << " ";
dp[2] = 0;
for (int i = 1; i < len; i++) {
int pre1 = dp[1];
int pre2 = dp[2];
int pre3 = dp[3];
fill(dp, dp + 4, 0x7f7f7f);
if (ob[i] != 1) dp[1] = pre1;
if (ob[i] != 2) dp[2] = pre2;
if (ob[i] != 3) dp[3] = pre3;
if (ob[i] != 1) dp[1] = min(dp[1], min(dp[2], dp[3]) + 1);
if (ob[i] != 2) dp[2] = min(dp[2], min(dp[1], dp[3]) + 1);
if (ob[i] != 3) dp[3] = min(dp[3], min(dp[2], dp[1]) + 1);
}
return min(dp[1], min(dp[2], dp[3]));
}
};