class Solution:
def splitLoopedString(self, strs):
# Preprocess: for each string, pick its lexicographically larger form (original or reversed)
strs = [max(s, s[::-1]) for s in strs]
ans = ''
n = len(strs)
for i in range(n):
s = strs[i]
rev = s[::-1]
for candidate in [s, rev]:
for k in range(len(candidate)):
# Form the new string by splitting at k, then concatenate rest
mid = candidate[k:] + candidate[:k]
rest = ''.join(strs[(i+1)%n:] + strs[:i])
temp = mid + rest
if temp > ans:
ans = temp
return ans
class Solution {
public:
string splitLoopedString(vector<string>& strs) {
int n = strs.size();
for (auto& s : strs) {
string rev = s;
reverse(rev.begin(), rev.end());
if (rev > s) s = rev;
}
string ans = "";
for (int i = 0; i < n; ++i) {
string s = strs[i];
string rev = s;
reverse(rev.begin(), rev.end());
for (const string& candidate : {s, rev}) {
for (int k = 0; k < candidate.size(); ++k) {
string mid = candidate.substr(k) + candidate.substr(0, k);
string rest = "";
for (int j = (i + 1) % n; j != i; j = (j + 1) % n)
rest += strs[j];
string temp = mid + rest;
if (temp > ans) ans = temp;
}
}
}
return ans;
}
};
class Solution {
public String splitLoopedString(String[] strs) {
int n = strs.length;
for (int i = 0; i < n; ++i) {
String rev = new StringBuilder(strs[i]).reverse().toString();
if (rev.compareTo(strs[i]) > 0) strs[i] = rev;
}
String ans = "";
for (int i = 0; i < n; ++i) {
String s = strs[i];
String rev = new StringBuilder(s).reverse().toString();
for (String candidate : new String[]{s, rev}) {
for (int k = 0; k < candidate.length(); ++k) {
String mid = candidate.substring(k) + candidate.substring(0, k);
StringBuilder rest = new StringBuilder();
for (int j = (i + 1) % n; j != i; j = (j + 1) % n)
rest.append(strs[j]);
String temp = mid + rest.toString();
if (temp.compareTo(ans) > 0) ans = temp;
}
}
}
return ans;
}
}
var splitLoopedString = function(strs) {
// Preprocess: maximize each string lexicographically
strs = strs.map(s => {
let rev = s.split('').reverse().join('');
return rev > s ? rev : s;
});
let ans = '';
let n = strs.length;
for (let i = 0; i < n; ++i) {
let s = strs[i];
let rev = s.split('').reverse().join('');
for (let candidate of [s, rev]) {
for (let k = 0; k < candidate.length; ++k) {
let mid = candidate.slice(k) + candidate.slice(0, k);
let rest = '';
for (let j = (i + 1) % n; j != i; j = (j + 1) % n)
rest += strs[j];
let temp = mid + rest;
if (temp > ans) ans = temp;
}
}
}
return ans;
};
Given a list of strings strs
, imagine concatenating them in a loop (so the last connects back to the first). You can reverse any of the individual strings (or leave them as they are), but you must maintain their order in the list. After making your choices, you can "split" the loop at any position (i.e., pick any rotation of the concatenated string as the starting point). Your task is to find the lexicographically largest string that can be obtained in this way.
At first glance, the problem seems to require checking all combinations of string reversals and all possible split positions, which could be computationally expensive. A brute-force approach would involve generating every possible arrangement, but this quickly becomes infeasible as the list grows.
To optimize, we notice two key things:
strs
, replace it with its lexicographically larger form (original or reversed). This ensures we always use the best possible version of each string.strs[i]
):k
in this string:k
, making the substring from k
to end the start of the result, followed by the substring from start to k
.strs[i+1]
to the end, then from strs[0]
to strs[i-1]
(to simulate the loop).This approach ensures we examine all valid combinations efficiently without unnecessary repetition.
Let's take strs = ["abc", "xyz"]
.
["cba", "zyx"]
m
is the total number of characters across all strings, and n
is the number of strings, the total number of splits to check is O(m * 2), since we try both orientations for each position in each string.The key to solving the Split Concatenated Strings problem efficiently is to recognize that, for each string, only its original and reversed forms matter. By always picking the lexicographically largest form for each string and systematically trying every possible split point and orientation, we can find the optimal solution without brute-forcing every combination. This approach is both elegant and efficient, leveraging careful preprocessing and smart enumeration of possibilities.