跳转至

555. 分割连接字符串 🔒

题目描述

给定一个字符串列表 strs,你可以将这些字符串连接成一个循环字符串,对于每个字符串,你可以选择是否翻转它。在所有可能的循环字符串中,你需要分割循环字符串(这将使循环字符串变成一个常规的字符串),然后找到字典序最大的字符串。

具体来说,要找到字典序最大的字符串,你需要经历两个阶段:

  1. 将所有字符串连接成一个循环字符串,你可以选择是否翻转某些字符串,并按照给定的顺序连接它们。
  2. 在循环字符串的某个位置分割它,这将使循环字符串从分割点变成一个常规的字符串。

你的工作是在所有可能的常规字符串中找到字典序最大的一个。

 

示例 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,对于每个字符串 \(s\),如果 \(s\) 的反转字符串 \(t\)\(s\) 大,那么我们就将 \(s\) 替换为 \(t\)

然后我们再枚举字符串数组 strs 的每个位置 \(i\) 作为分割点,将字符串数组 strs 拆成两部分,分别为 \(strs[i + 1:]\)\(strs[:i]\),然后将这两部分拼接起来,得到一个新的字符串 \(t\)。接下来,我们枚举当前字符串 \(strs[i]\) 的每个位置 \(j\),其后缀部分为 \(a=strs[i][j:]\),前缀部分为 \(b=strs[i][:j]\),那么我们可以将 \(a\), \(t\)\(b\) 拼接起来,得到一个新的字符串 \(cur\),如果 \(cur\) 比当前答案大,那么我们就更新答案。这是将 \(strs[i]\) 翻转后的情况,我们还需要考虑 \(strs[i]\) 不翻转的情况,即将 \(a\), \(t\)\(b\) 的顺序反过来拼接,得到一个新的字符串 \(cur\),如果 \(cur\) 比当前答案大,那么我们就更新答案。

最后,我们返回答案即可。

时间复杂度 \(O(n^2)\),空间复杂度 \(O(n)\)。其中 \(n\) 为字符串数组 strs 的长度。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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)
}

评论

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy