[lintcode]876. 连接字符串

链接:http://lintcode.com/zh-cn/problem/split-concatenated-strings/

给定一个字符串列表,您可以将这些字符串连接到一个循环中,在这个循环中,您可以选择将其反转。在所有可能的循环中,您需要在删除循环之后找到字母顺序最大的字符串,这将使循环字符串成为一个普通的字符串。

具体来说,要找到字母顺序上最大的字符串,您需要经历两个阶段:
  1:将所有字符串连接到一个循环中,在这个循环中,您可以反转某些字符串,并按照给定的顺序将它们连接起来。
  2:在循环的任意位置切割并制造一个断点,这将使从字符处开始循环的字符串成为一个正常的字符串,你的任务是在所有可能的规则字符串中找到字母顺序上最大的一个。

 注意事项

输入字符串只包含小写字母.
所有字符串的总长度不会超过1000.

样例

给定 str = ["abc", "xyz"], 返回 "zyxcba"

解释:
你可以得到循环字符串“-abcxyz-”,“-abczyx-”,“-cbaxyz-”,“-cbazyx-”,
其中“-”表示循环状态。
答案字符串串从第四个字符串中得来,
你可以从中间的字母a中剪切,得到“zyxcba”。
思路:


让我们将其连接起来,连接的时候对于每个字符串我们可以选择翻转或者不翻转,在行程的大的字符串上找一个位置cut掉,将该位置当作首字符,前面的字符串移动到末尾去,问怎么cut能使字符串的字母顺序大。刚开始博主想,既然要让最终字符串字母顺序最大,那么每一个字符串当然要尽可能的大了,所以如果其翻转字符串的字母顺序大的话,就要对字符串进行翻转。然后在组成的字符串中找最大的字符进行cut,然而这种思路不一定能得到正确的结果。比如字符串数组["lc", "love", "ydc"],如果按照博主之前的思路得到的字符串应该为"ydclclove",但正确结果应该是"ylclovecd"。我们可出来正确的答案中cut位置所在的字符串ydc,虽然cdy小于ydc,但还是翻转了。但是其他的字符都是按照字母顺序来确定要不要翻转的,那么我们可以得出这样的结论,只有cut所在的字符串的翻转可能不按规律。那么我们如何确定cut位置呢,其实没有太好的办法,只能遍历每一个字母。我们首先来根据字母顺序确定要不要翻转每一个字符串,将字母顺序大的连成一个字符串,然后遍历每一个字符串,在每一个字符串中遍历每一个位置,将当前遍历的字符串后面的所有字符串跟前面所有字符串先连起来,存入mid中,然后取出当前遍历的字符串中当前遍历的位置及其后面的字符取出,连上mid,然后再连上当前位置前面的字符,然后跟结果res比较,取较大者存入结果res。这里我们可以进行小优化,如果cut位置的字母大于等于结果res的首字母,我们才进行对比更新。注意我们在遍历每个字符串时,要将其翻转字符串的每一位也遍历了,这样才能涵盖所有的情况。


class Solution {
public:
    /**
     * @param strs: a list of string
     * @return: return a string
     */
    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;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值