Welcome to Subscribe On Youtube

Formatted question description: https://leetcode.ca/all/555.html

555. Split Concatenated Strings

Level

Medium

Description

Given a list of strings, you could concatenate these strings together into a loop, where for each string you could choose to reverse it or not. Among all the possible loops, you need to find the lexicographically biggest string after cutting the loop, which will make the looped string into a regular one.

Specifically, to find the lexicographically biggest string, you need to experience two phases:

  1. Concatenate all the strings into a loop, where you can reverse some strings or not and connect them in the same order as given.
  2. Cut and make one breakpoint in any place of the loop, which will make the looped string into a regular one starting from the character at the cutpoint.

And your job is to find the lexicographically biggest one among all the possible regular strings.

Example:

Input: “abc”, “xyz”

Output: “zyxcba”

Explanation: You can get the looped string “-abcxyz-“, “-abczyx-“, “-cbaxyz-“, “-cbazyx-“, where ‘-‘ represents the looped status. The answer string came from the fourth looped one, where you could cut from the middle character ‘a’ and get “zyxcba”.

Note:

  1. The input strings will only contain lowercase letters.
  2. The total length of all the strings will not over 1,000.

Solution

If the split takes place inside a string, then only this string and its reversed string should be both tried, and for the remaining strings, a string that is lexicographically bigger will always lead to a lexicographically bigger result. So first loop over strs and for each string, reverse it if the reversed string is lexicographically bigger than the original string.

Then for each string in strs, try all possible positions of splitting and form each concatenated string with each splitting position, and return the lexicographically biggest string.

  • class Solution {
        public String splitLoopedString(String[] strs) {
            int length = strs.length;
            for (int i = 0; i < length; i++) {
                String str = strs[i];
                String str2 = new StringBuffer(str).reverse().toString();
                if (str2.compareTo(str) > 0)
                    strs[i] = str2;
            }
            String biggestStr = "";
            for (int i = 0; i < length; i++) {
                String str = strs[i];
                String str2 = new StringBuffer(str).reverse().toString();
                String[] tempArray = {str, str2};
                for (String curStr : tempArray) {
                    int curLength = curStr.length();
                    for (int j = 0; j < curLength; j++) {
                        StringBuffer sb = new StringBuffer(curStr.substring(j));
                        int index = (i + 1) % length;
                        for (int k = 1; k < length; k++) {
                            sb.append(strs[index]);
                            index = (index + 1) % length;
                        }
                        sb.append(curStr.substring(0, j));
                        String curTotalStr = sb.toString();
                        if (curTotalStr.compareTo(biggestStr) > 0)
                            biggestStr = curTotalStr;
                    }
                }
            }
            return biggestStr;
        }
    }
    
  • class Solution(object):
      def splitLoopedString(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        ans = ""
        for i in range(len(strs)):
          strs[i] = max(strs[i], strs[i][::-1])
    
        for i, word in enumerate(strs):
          for start in [word, word[::-1]]:
            for cut in range(len(start)):
              ans = max(ans, start[cut:] + "".join(strs[i + 1:] + strs[:i]) + start[:cut])
    
        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)
    }
    

All Problems

All Solutions