力扣514 自由之路
知识点:
- 思路是贪心->暴搜->动态规划
- 由于数组只与前一列有关,因此写成了滚动数组的形式,只是听说叫滚动数组,想法是很自然的
class Solution {
public:
//直观上贪心,但是不能保证最优
//每次的状态有限,且到该状态后,只要记录了该状态下所有的可能,就能直接推出下一步
//与上次的买卖股票的情况差不多,只不过一个状态只有0和1,一个状态是不确定,其实都一样
//之所以能比枚举快是因为舍弃了那些没有可能的分支
//dp[i][j] += 1 + min(dp[i-1][k] + dis(j,k)), j为key[i]在ring上的位置,k为key[i-1]在ring上的位置
int findRotateSteps(string ring, string key) {
int n = ring.size();
int m = key.size();
vector<vector<int>> st(26);
vector<int> dp(n,0);
for(int i = 0; i < n; ++i){
st[(int)(ring[i] - 'a')].push_back(i);
if(ring[i] == key[0]) dp[i] += (1+min(i,n-i));
}
for(int i = 1; i < m; ++i){
vector<int> dp1(n,0);
for(auto& idxNow : st[(int)(key[i]-'a')]){
int minStep = 1000000;
for(auto& idxOld : st[(int)(key[i-1]-'a')]){
int diff = abs(idxNow-idxOld);
int CurStep =1 + min(diff, n - diff) + dp[idxOld];
if(CurStep < minStep) minStep = CurStep;
}
dp1[idxNow] = minStep;
}
dp = dp1;
}
int res = 1000000;
for(auto& idxRes : st[(int)(key[m-1]-'a')]){
if(dp[idxRes] < res) res = dp[idxRes];
}
return res;
}
};