力扣514 自由之路

力扣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;
    }
};
原文地址:https://www.cnblogs.com/jinjin-2018/p/13960706.html