Thanks for your post, but actually we can move these two lines out of the loop, since for each iteration of k they are the same.

for (int j=i+1; j<n; ++j) str1 += strs[j]; // Concatenate all the string behind the strs[i] for (int j=0; j<i; ++j) str2 += strs[j]; // Concatenate all the string before the strs[i]In fact, we even don't need to recompute the concatenated middle part every time. When we iterate the "cutting string", we just need delete the first string in the middle part and add one string to the last part as I did in my code.

public static String splitLoopedString(String[] strs) { int n = strs.length; for (int i = 0; i < n; i++) { String rev = new StringBuilder(strs[i]).reverse().toString(); if (strs[i].compareTo(rev) < 0) strs[i] = rev; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < n-1; i++) sb.append(strs[i]); String mid = sb.toString(), result = mid+strs[n-1]; for (int i = 0; i < n; i++) { String str = strs[i], rev = new StringBuilder(str).reverse().toString(); mid = mid.substring(str.length())+strs[(i+n-1)%n]; for (int j = 0; j <= str.length(); j++) { String s1 = str.substring(j)+mid+str.substring(0, j), s2 = rev.substring(j)+mid+rev.substring(0, j); if (s1.compareTo(s2) >= 0 && s1.compareTo(result) > 0) result = s1; else if (s2.compareTo(s1) >= 0 && s2.compareTo(result) > 0) result = s2; } } return result; }