返回介绍

solution / 0500-0599 / 0555.Split Concatenated Strings / README

发布于 2024-06-17 01:03:59 字数 5305 浏览 0 评论 0 收藏 0

555. 分割连接字符串

English Version

题目描述

给定一个字符串列表 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 的长度。

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)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文