WEEK#10 Dynamic Programming_Freedom Trail

Description of the Problem

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.

Example:

image.png

Input: ring = "godding", key = "gd"
Output: 4
Explanation:For the first key character 'g', since it is already in place, we just need 1 step to spell this character.For the second key character 'd', we need to rotate the ring "godding" anticlockwise by two steps to make it become "ddinggo".Also, we need 1 more step for spelling.So the final output is 4.

Note:
Length of both ring and key will be in range 1 to 100.
There are only lowercase letters in both strings and might be some duplicate characters in both strings.
It's guaranteed that string key could always be spelled by rotating the string ring.


Thinking Process

All letters in ring have a smallest cost to travel to another letter in ring.
So for a ring of size n, we construct a 2-d array M[n][n], in which M[i][j] means the smallest cost travel from ring[i] to ring[j].
In this way, what we need will be :

Pointer and Result are initialized as 0.
For i ∈ (0, key.length)
1. Find j, so that ring[j] = key[i];
2. Result += M[Pointer][j];
3. Pointer = j;

This method can only work out very limited test cases, for it is rather static than dynamic. It is unable to take all the moves into account, thus can't work out the best solution.
Every step that the algorithm takes could all have an influence on the result, yet this method can only choose the smallest cost at current step, overlooking that taking the smallest step now may result in a bigger cost later on.
For example, ring = "iotfo", key = "fioot"
When currently pointing to 'i', and wish to go to 'o', the cost of left-side 'o' and right-side 'o' are the same, but only by taking the right-side one can we get the best solution, cause its closer to 't' than the left-side one.

class Solution {
public:
    int findRotateSteps(string ring, string key) {
        int length = ring.size();
        vector<vector<int>> Matrix = construct(length);
        int result = 0, pointer = 0;
        for (int i = 0; i < key.length(); i++) {
            int findleft = 0, findright = 0;
            bool jflag = false;
            for (int j = pointer; j < length; j++) {
                if (ring[j] == key[i]) {
                    findright = j;
                    break;
                }
                if (j == length-1 && jflag == false) {
                    j = -1;
                    jflag = true;
                }
            }
            bool kflag = false;
            for (int k = pointer; k >= 0; k--) {
                if (ring[k] == key[i]) {
                    findleft = k;
                    break;
                }
                if (k == 0 && kflag == false) {
                    k = length;
                    kflag = true;
                }
            }
            int smaller = Matrix[pointer][findleft] <= Matrix[pointer][findright] ? Matrix[pointer][findleft] : Matrix[pointer][findright];
            result += smaller;
            if (Matrix[pointer][findleft] <= Matrix[pointer][findright])
                pointer = findleft;
            else
                pointer = findright;
        }
        return result;
    }

    vector<vector<int>> construct(int length) {
        vector<vector<int>> Matrix;
        Matrix.resize(length);
        for (int i = 0; i < length; i++)
            Matrix[i].resize(length);

        for (int i = 0; i < length; i++)
            Matrix[i][i] = 1;

        for (int i = 0; i < length; i++) {
            int count = 1;
            bool flag = false;
            for (int j = i + 1; j < length; j++) {
                if (flag == false)
                    Matrix[i][j] = ++count;
                if (count >= length / 2 + 1 && flag == false) {
                    flag = true;
                    continue;
                }
                if (flag) {
                    if (length % 2 == 1)
                        Matrix[i][j] = count--;
                    else
                        Matrix[i][j] = --count;
                }
            }
        }

        for (int i = 1; i < length; i++) {
            for (int j = i - 1; j >= 0; j--) {
                Matrix[i][j] = Matrix[j][i];
            }
        }
        return Matrix;
    }
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末娇斑,一起剝皮案震驚了整個(gè)濱河市吱型,隨后出現(xiàn)的幾起案子势篡,更是在濱河造成了極大的恐慌,老刑警劉巖候醒,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異漂辐,居然都是意外死亡显拳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進(jìn)店門伪很,熙熙樓的掌柜王于貴愁眉苦臉地迎上來戚啥,“玉大人,你說我怎么就攤上這事锉试∶ㄊ” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長炫彩。 經(jīng)常有香客問我匾七,道長,這世上最難降的妖魔是什么江兢? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任昨忆,我火速辦了婚禮,結(jié)果婚禮上杉允,老公的妹妹穿的比我還像新娘邑贴。我一直安慰自己,他們只是感情好叔磷,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布拢驾。 她就那樣靜靜地躺著,像睡著了一般改基。 火紅的嫁衣襯著肌膚如雪繁疤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天秕狰,我揣著相機(jī)與錄音稠腊,去河邊找鬼。 笑死鸣哀,一個(gè)胖子當(dāng)著我的面吹牛架忌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播我衬,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼叹放,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了挠羔?” 一聲冷哼從身側(cè)響起井仰,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎破加,沒想到半個(gè)月后糕档,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拌喉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年速那,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尿背。...
    茶點(diǎn)故事閱讀 38,664評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡端仰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出田藐,到底是詐尸還是另有隱情荔烧,我是刑警寧澤吱七,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站鹤竭,受9級特大地震影響踊餐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜臀稚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一吝岭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吧寺,春花似錦窜管、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赖条,卻和暖如春失乾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纬乍。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工仗扬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蕾额。 一個(gè)月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像彼城,于是被迫代替她去往敵國和親诅蝶。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 今天姐姐說她的小狗雪花記性越來越不好了代嗤,經(jīng)常在外面轉(zhuǎn)幾圈才想起回家棘钞,視力不濟(jì),聽力也不好干毅,還胡亂小便宜猜。。硝逢。好像患上...
    悠然的橋閱讀 456評論 0 7
  • 《作為意志和表象的世界》開篇第一句就是:“世界是我的表象”姨拥。在叔本華看來绅喉,整個(gè)世界首先是作為人類的印象而存在,對人...
    木卯丁閱讀 173評論 0 0
  • 今天和朋友聊天叫乌,她說覺得我是幸運(yùn)的柴罐,我也值得這份幸運(yùn)『┘椋可是直到聊天結(jié)束革屠,我都不解她口中的幸運(yùn),于我是什么膀藐。1 自小...
    晨creezy閱讀 245評論 0 0