comments | difficulty | edit_url | tags | |||
---|---|---|---|---|---|---|
true |
中等 |
|
给定一个字符串列表 strs
,你可以将这些字符串连接成一个循环字符串,对于每个字符串,你可以选择是否翻转它。在所有可能的循环字符串中,你需要分割循环字符串(这将使循环字符串变成一个常规的字符串),然后找到字典序最大的字符串。
具体来说,要找到字典序最大的字符串,你需要经历两个阶段:
- 将所有字符串连接成一个循环字符串,你可以选择是否翻转某些字符串,并按照给定的顺序连接它们。
- 在循环字符串的某个位置分割它,这将使循环字符串从分割点变成一个常规的字符串。
你的工作是在所有可能的常规字符串中找到字典序最大的一个。
示例 1:
输入: strs = ["abc","xyz"] 输出: "zyxcba" 解释: 你可以得到循环字符串 "-abcxyz-", "-abczyx-", "-cbaxyz-", "-cbazyx-",其中 '-' 代表循环状态。 答案字符串来自第四个循环字符串, 你可以从中间字符 'a' 分割开然后得到 "zyxcba"。
示例 2:
输入: strs = ["abc"] 输出: "cba"
提示:
1 <= strs.length <= 1000
1 <= strs[i].length <= 1000
1 <= sum(strs[i].length) <= 1000
strs[i]
只包含小写英文字母
我们先遍历字符串数组 strs
,对于每个字符串
然后我们再枚举字符串数组 strs
的每个位置 strs
拆成两部分,分别为
最后,我们返回答案即可。
时间复杂度 strs
的长度。
class Solution:
def splitLoopedString(self, strs: List[str]) -> str:
strs = [s[::-1] if s[::-1] > s else s for s in strs]
ans = ''.join(strs)
for i, s in enumerate(strs):
t = ''.join(strs[i + 1 :]) + ''.join(strs[:i])
for j in range(len(s)):
a = s[j:]
b = s[:j]
ans = max(ans, a + t + b)
ans = max(ans, b[::-1] + t + a[::-1])
return ans
class Solution {
public String splitLoopedString(String[] strs) {
int n = strs.length;
for (int i = 0; i < n; ++i) {
String s = strs[i];
String t = new StringBuilder(s).reverse().toString();
if (s.compareTo(t) < 0) {
strs[i] = t;
}
}
String ans = "";
for (int i = 0; i < n; ++i) {
String s = strs[i];
StringBuilder sb = new StringBuilder();
for (int j = i + 1; j < n; ++j) {
sb.append(strs[j]);
}
for (int j = 0; j < i; ++j) {
sb.append(strs[j]);
}
String t = sb.toString();
for (int j = 0; j < s.length(); ++j) {
String a = s.substring(j);
String b = s.substring(0, j);
String cur = a + t + b;
if (ans.compareTo(cur) < 0) {
ans = cur;
}
cur = new StringBuilder(b)
.reverse()
.append(t)
.append(new StringBuilder(a).reverse().toString())
.toString();
if (ans.compareTo(cur) < 0) {
ans = cur;
}
}
}
return ans;
}
}
class Solution {
public:
string splitLoopedString(vector<string>& strs) {
for (auto& s : strs) {
string t{s.rbegin(), s.rend()};
s = max(s, t);
}
int n = strs.size();
string ans = "";
for (int i = 0; i < strs.size(); ++i) {
auto& s = strs[i];
string t;
for (int j = i + 1; j < n; ++j) {
t += strs[j];
}
for (int j = 0; j < i; ++j) {
t += strs[j];
}
for (int j = 0; j < s.size(); ++j) {
auto a = s.substr(j);
auto b = s.substr(0, j);
auto cur = a + t + b;
if (ans < cur) {
ans = cur;
}
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
cur = b + t + a;
if (ans < cur) {
ans = cur;
}
}
}
return ans;
}
};
func splitLoopedString(strs []string) (ans string) {
for i, s := range strs {
t := reverse(s)
if s < t {
strs[i] = t
}
}
for i, s := range strs {
sb := &strings.Builder{}
for _, w := range strs[i+1:] {
sb.WriteString(w)
}
for _, w := range strs[:i] {
sb.WriteString(w)
}
t := sb.String()
for j := 0; j < len(s); j++ {
a, b := s[j:], s[0:j]
cur := a + t + b
if ans < cur {
ans = cur
}
cur = reverse(b) + t + reverse(a)
if ans < cur {
ans = cur
}
}
}
return ans
}
func reverse(s string) string {
t := []byte(s)
for i, j := 0, len(t)-1; i < j; i, j = i+1, j-1 {
t[i], t[j] = t[j], t[i]
}
return string(t)
}