1. 程式人生 > >[LeetCode] Split Concatenated Strings 分割串聯字串

[LeetCode] Split Concatenated Strings 分割串聯字串

Given a list of strings, you could concatenate these strings together into a loop, where for each string you could choose to reverse it or not. Among all the possible loops, you need to find the lexicographically biggest string after cutting the loop, which will make the looped string into a regular one.

Specifically, to find the lexicographically biggest string, you need to experience two phases:

  1. Concatenate all the strings into a loop, where you can reverse some strings or not and connect them in the same order as given.
  2. Cut and make one breakpoint in any place of the loop, which will make the looped string into a regular one starting from the character at the cutpoint.

And your job is to find the lexicographically biggest one among all the possible regular strings.

Example:

Input: "abc", "xyz"
Output: "zyxcba"
Explanation: You can get the looped string "-abcxyz-", "-abczyx-", "-cbaxyz-", "-cbazyx-", 
where '-' represents the looped status.
The answer string came from the fourth looped one,
where you could cut from the middle character 'a' and get "zyxcba".

Note:

  1. The input strings will only contain lowercase letters.
  2. The total length of all the strings will not over 1,000.

這道題給了我們一些字串,讓我們將其連線起來,連線的時候對於每個字串我們可以選擇翻轉或者不翻轉,在行程的大的字串上找一個位置cut掉,將該位置當作首字元,前面的字串移動到末尾去,問怎麼cut能使字串的字母順序大。剛開始博主想,既然要讓最終字串字母順序最大,那麼每一個字串當然要儘可能的大了,所以如果其翻轉字串的字母順序大的話,就要對字串進行翻轉。然後在組成的字串中找最大的字元進行cut,然而這種思路不一定能得到正確的結果。比如字串陣列["lc", "love", "ydc"],如果按照博主之前的思路得到的字串應該為"ydclclove",但正確結果應該是"ylclovecd"。我們可出來正確的答案中cut位置所在的字串ydc,雖然cdy小於ydc,但還是翻轉了。但是其他的字元都是按照字母順序來確定要不要翻轉的,那麼我們可以得出這樣的結論,只有cut所在的字串的翻轉可能不按規律。那麼我們如何確定cut位置呢,其實沒有太好的辦法,只能遍歷每一個字母。我們首先來根據字母順序確定要不要翻轉每一個字串,將字母順序大的連成一個字串,然後遍歷每一個字串,在每一個字串中遍歷每一個位置,將當前遍歷的字串後面的所有字串跟前面所有字串先連起來,存入mid中,然後取出當前遍歷的字串中當前遍歷的位置及其後面的字元取出,連上mid,然後再連上當前位置前面的字元,然後跟結果res比較,取較大者存入結果res。這裡我們可以進行小優化,如果cut位置的字母大於等於結果res的首字母,我們才進行對比更新。注意我們在遍歷每個字串時,要將其翻轉字串的每一位也遍歷了,這樣才能涵蓋所有的情況,參見程式碼如下:

class Solution {
public:
    string splitLoopedString(vector<string>& strs) {
        if (strs.empty()) return "";
        string s = "", res = "a";
        int n = strs.size(), cur = 0;
        for (string str : strs) {
            string t = string(str.rbegin(), str.rend());
            s += str > t ? str : t;
        }
        for (int i = 0; i < n; ++i) {          
            string t1 = strs[i], t2 = string(t1.rbegin(), t1.rend());
            string mid = s.substr(cur + t1.size()) + s.substr(0, cur);
            for (int j = 0; j < strs[i].size(); ++j) {
                if (t1[j] >= res[0]) res = max(res, t1.substr(j) + mid + t1.substr(0, j));
                if (t2[j] >= res[0]) res = max(res, t2.substr(j) + mid + t2.substr(0, j));
            }
            cur += strs[i].size();
        }
        return res;
    }
};

參考資料: