题目大意:
有一段数组,长度为
n
n
n,可以从第一步出发,也可以从第二部出发。可以一步一步走,也可以两步两步走。每次从一个地方离开时需要交钱。问需要的最小花费是多少。
思路其实很简单,维护每一步的最小花费。走到
i
i
i步时,可以从
i
−
1
i - 1
i−1步来的,也可以是
i
−
2
i -2
i−2步来的。
- 从 i − 1 i - 1 i−1步来的,要交 i − 1 i - 1 i−1步的钱,就需要在 i − 1 i - 1 i−1步来的花费上加上 i − 1 i - 1 i−1步的钱。
- 从 i − 2 i - 2 i−2步来的,要交 i − 2 i - 2 i−2步的钱,就需要在 i − 2 i - 2 i−2步来的花费上加上 i − 2 i - 2 i−2步的钱。
比较以上两个的大小,去最小值作为走到
i
i
i步的最小花费。由于需要走出去,也就是要走到最后一步的还要后面一步,所以干脆再加维护一个
n
+
1
n + 1
n+1步。最后时间复杂度
O
(
N
)
O(N)
O(N)。
这里维护每一步的最小花费就有很多的数据结构了。比如数组
m
i
n
c
o
s
t
[
i
]
mincost[i]
mincost[i],空间复杂度
O
(
N
)
O(N)
O(N):
int mincost[1005];
int length = cost.size() + 1;
mincost[0] = 0;
mincost[1] = 0;
for(int i = 2; i < length; i++){
mincost[i] = min(mincost[i - 1] + cost[i - 1], mincost[i - 2] + cost[i - 2]);
}
return mincost[length - 1];
也有用vector维护的,空间复杂度 O ( N ) O(N) O(N):
int n = cost.size();
vector<int> mincost(n+1,0);
for(int i=2; i<=n; i++){
mincost[i] = min(mincost[i - 1] + cost[i - 1], mincost[i - 2] + cost[i - 2]);
}
return mincost[n];
再比如只用三个变量保存中间结果,空间复杂度 O ( 1 ) O(1) O(1):
int mincost = 0, mincost1 = 0, mincost2 = 0;
int length = cost.size() + 1;
mincost1 = 0;
mincost2 = 0;
for(int i = 2; i < length; i++){
mincost = min(mincost1 + cost[i - 1], mincost2 + cost[i - 2]);
mincost2 = mincost1;
mincost1 = mincost;
}
return mincost;
虽然时间复杂度都一样,但是三个方法执行的时间不一样,最快的是vector,用时
4
m
s
4ms
4ms;其次是数组,用时
8
m
s
8ms
8ms,最慢的是三个变量,用时
15
m
s
15ms
15ms。
还望大神解释!