514. Freedom Trail 【Hard】 动态规划

来源:互联网 发布:b2b2c php开源 编辑:程序博客网 时间:2024/06/05 21:02

问题:给定一个圆环(初始字符为第一个)和一个字符串,进行如下操作直至打印出此字符串——

操作一:打印出圆环的第一个字符

操作二:把圆环顺时针或逆时针转一个位置

问打印此字符串最少需要多少步操作?


思路:用动归解决。将字符串拆分为单个字符,每一轮只考虑当前要打印的字符(假设为X)——对圆环上的每个X,求出其从上一轮到这一轮的最小距离dist(X)。

距离指圆环上的顺时针or逆时针最短距离。

如果是第一轮,那么每个X的dist(X)为它的位置到0的距离再加一(加一是因为要打印)

如果是第N轮(N>1),假设上一轮要打印的字符为S(则每个S都在上一轮都已经有一个dist值了),那么每个X的dist(X)为:它的位置到圆环上各个S的距离分别加上dist(S)的最小值,再加一(加一是因为要打印)

最终动归出最后一个字符Z,在dist(Z)中找到最小值打印出来就可以了。


难度还可以,主要是明确了思路就好了,时间都花在了debug上面。


vector<int> max_vector_initializer(100, 9999999);int min_num(int x, int y) {if (x > y) return y;else return x;}int abs(int d) {if (d > 0) return d;else return -d;}int C2I(char c) {return (int)(c - 'a');}int dist(int p1, int p2, int lr) {int abs_dis = abs(p1 - p2);return min_num(abs_dis, lr - abs_dis);}class Solution {public:    int findRotateSteps(string ring, string key) {        vector<int> mapping[26];int lr = ring.size();int lk = key.size();int pos;for (int i = 0; i < lr; ++i) {pos = C2I(ring[i]);mapping[pos].push_back(i);}                vector<int> a(100, 9999999);        vector<int> b(100, 9999999);for (int it = 0; it < lk; ++it) {            b = a; // b is the previous state            a = max_vector_initializer; // initialize a to a max vector            int prev, next, d;            int prev_c = (it == 0 ? -1 : C2I(key[it - 1]));            int next_c = C2I(key[it]);            if (prev_c == -1) {                for (int j = 0; j < mapping[next_c].size(); ++j) {                    next = mapping[next_c][j];                    a[next] = dist(0, next, lr) + 1;                }            } else {                for (int i = 0; i < mapping[prev_c].size(); ++i) {                    for (int j = 0; j < mapping[next_c].size(); ++j) {                        prev = mapping[prev_c][i];                        next = mapping[next_c][j];                        d = dist(prev, next, lr);                        a[next] = min_num(a[next], b[prev] + 1 + d);                    }                }            }}                        int pos_c = C2I(key[lk - 1]);        int _min_ = 9999999;        for (int i = 0; i < mapping[pos_c].size(); ++i) {            pos = mapping[pos_c][i];            if (_min_ > a[pos]) {                _min_ = a[pos];            }        }        return _min_;    }};


原创粉丝点击