题目描述: 给定一个字符串列表,你可以将这些字符串连接成一个循环字符串,对于每个字符串,你可以选择是否翻转它。在所有可能的循环字符串中,你需要分割循环字符串(这将使循环字符串变成一个常规的字符串),然后找到字典序最大的字符串。
具体来说,要找到字典序最大的字符串,你需要经历两个阶段:
将所有字符串连接成一个循环字符串,你可以选择是否翻转某些字符串,并按照给定的顺序连接它们。 在循环字符串的某个位置分割它,这将使循环字符串从分割点变成一个常规的字符串。 你的工作是在所有可能的常规字符串中找到字典序最大的一个。
示例: 输入: “abc”, “xyz” 输出: “zyxcba” 解释: 你可以得到循环字符串 “-abcxyz-”, “-abczyx-”, “-cbaxyz-”, “-cbazyx-”, 其中 ‘-’ 代表循环状态。 答案字符串来自第四个循环字符串, 你可以从中间字符 ‘a’ 分割开然后得到 “zyxcba”。
注意: 输入字符串只包含小写字母。 所有字符串的总长度不会超过 1,000。
方法1: 主要思路: (1)广度优先方法,不通过;
class Solution { public: string splitLoopedString(vector<string>& strs) { queue<string> q; q.push(strs[0]); reverse(strs[0].begin(),strs[0].end()); q.push(strs[0]); for(int i=1;i<strs.size();++i){ string rev_str=strs[i]; reverse(rev_str.begin(),rev_str.end()); int cur_size=q.size(); while(cur_size--){ string cur_str=q.front(); q.pop(); q.push(cur_str+strs[i]); q.push(cur_str+rev_str); } } string max_str=q.front(); int len=max_str.size(); while(!q.empty()){ string cur_str=q.front(); q.pop(); max_str=max(max_str,cur_str); for(int i=1;i<len;++i){ max_str=max(max_str,cur_str.substr(i,len-i)+cur_str.substr(0,i)); } } return max_str; } };方法2: 主要思路: (1)若不考虑在某个字符串内部进行分割,则一定是各个字符串本身或其反转的字符串中较大字符串合起来的字符串的组合; (2)故可以先对原来的字符串元素进行转换,替换成较大的字符串,然后对各个字符串可能作为反转分割点的内部位置进行判断;
class Solution { public: string splitLoopedString(vector<string>& strs) { //获得各个字符串的较大值 for(string& str:strs){ string tmp(str.rbegin(),str.rend()); if(tmp>str){ str=tmp; } } string res; for(int i=0;i<strs.size();++i){ string tmp; //获得其它的字符串组成的字符串 for(int j=i+1;j!=strs.size();++j){ tmp+=strs[j]; } for(int j=0;j!=i;++j){ tmp+=strs[j]; } //对当前字符串内的位置作为分割点的各个可能组成字符串 string cur_str=strs[i]; for(int j=0;j<cur_str.size();++j){ string cur_tmp=cur_str.substr(j)+tmp+cur_str.substr(0,j); res=max(res,cur_tmp); } //反转后的情形 reverse(cur_str.begin(),cur_str.end()); for(int j=0;j<cur_str.size();++j){ string cur_tmp=cur_str.substr(j)+tmp+cur_str.substr(0,j); res=max(res,cur_tmp); } } //返回最大的组成 return res; } };