Leetcode freedom trail

題目

In the video game Fallout 4, the quest “Road to Freedom” requires players to reach a metal dial called the “Freedom Trail Ring”, and use the dial to spell a specific keyword in order to open the door.

Given a string ring, which represents the code engraved on the outer ring and another string key, which represents the keyword needs to be spelled. You need to find the minimum number of steps in order to spell all the characters in the keyword.

Initially, the first character of the ring is aligned at 12:00 direction. You need to spell all the characters in the string key one by one by rotating the ring clockwise or anticlockwise to make each character of the string key aligned at 12:00 direction and then by pressing the center button.
At the stage of rotating the ring to spell the key character key[i]:
You can rotate the ring clockwise or anticlockwise one place, which counts as 1 step. The final purpose of the rotation is to align one of the string ring’s characters at the 12:00 direction, where this character must equal to the character key[i].
If the character key[i] has been aligned at the 12:00 direction, you need to press the center button to spell, which also counts as 1 step. After the pressing, you could begin to spell the next character in the key (next stage), otherwise, you’ve finished all the spelling.

題目分析

這道題是通過扭動轉盤來獲取相應的字符,從而組成key。題目的要求是返回最小的步驟。

該題是尋找最小的路徑步驟,因此所有的步驟都應該遍歷,這裏就使用DP思想。DP部分其實不是很難,和書上的edit distance是一致的,找到兩個字符串之間的distance。

對於我而言,難點在於旋轉時的下標獲取….一開始想到使用edit distance 的方法來解決這道題,自然就會想到構建一個[key.length() + 1][ring.length() + 1]大小的dp數組來記錄步驟數,但在這裏,那個旋轉後的下標獲取就有點問題了,因此最終換成[key.length()][ring.length()]大小的dp數組。

解題步驟:
1. 首先建立dp[key.length][ring.lenth]的數組,初始化爲最大值0X7FFFFFFF。dp(i,j)表示第i個key,當前位置爲j的最小step。
2. 從左到右,從上往下依次尋找最短的路徑。如果key[i]和ring[j]不相等,則直接跳過。否則,從j位置開始,同時向左、右兩邊進行尋找,找到i-1步存在的路徑,尋找路徑的最小值。
3. 尋找完路徑後,需要+1,這一步是press button
3. 最終結果返回,max(dp[key.length()1][j])0j<ring.length

源代碼

class Solution {
public:
    int findRotateSteps(string ring, string key) {
        vector<vector<int> > dp(key.size(), vector<int>(ring.size(), 0x7ffffff));

        int ans = 0x0fffffff;
        //compute
        //dp(i, j) 表示完成第i個key,前一跳是i
        for (int i = 0; i < key.size(); i++) {
            for (int j = 0; j < ring.size(); j++) {
                if (key[i] == ring[j]) {
                    if (i > 0) {
                        for (int k = 0; k <= ring.size() / 2; k++) {
                            int cw = (j + k) % ring.size();
                            int ac = (j - k + ring.size()) % ring.size();
                            int walk = 0x7fffffff;
                            if (dp[i - 1][cw] != 0x7ffffff || dp[i - 1][ac] != 0x7ffffff)
                                walk = min(dp[i - 1][cw], dp[i - 1][ac]);
                            else 
                                walk = dp[i][j];
                            //rotate ring
                            dp[i][j] = min(dp[i][j], walk + k);

                        }
                    } else {
                        dp[i][j] = min(j, int(ring.length()) - j);
                    }
                    //press button
                    dp[i][j]++;
                }
                //cout << dp[i][j] << " ";
            }
            //cout << endl;
        }
        for (int i = 0; i < ring.size(); i++) {
            ans = min(ans, dp[key.size() - 1][i]);
        }
        return ans;
    }

};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章