返回介绍

solution / 2100-2199 / 2182.Construct String With Repeat Limit / README_EN

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

2182. Construct String With Repeat Limit

中文文档

Description

You are given a string s and an integer repeatLimit. Construct a new string repeatLimitedString using the characters of s such that no letter appears more than repeatLimit times in a row. You do not have to use all characters from s.

Return _the lexicographically largest _repeatLimitedString _possible_.

A string a is lexicographically larger than a string b if in the first position where a and b differ, string a has a letter that appears later in the alphabet than the corresponding letter in b. If the first min(a.length, b.length) characters do not differ, then the longer string is the lexicographically larger one.

 

Example 1:

Input: s = "cczazcc", repeatLimit = 3
Output: "zzcccac"
Explanation: We use all of the characters from s to construct the repeatLimitedString "zzcccac".
The letter 'a' appears at most 1 time in a row.
The letter 'c' appears at most 3 times in a row.
The letter 'z' appears at most 2 times in a row.
Hence, no letter appears more than repeatLimit times in a row and the string is a valid repeatLimitedString.
The string is the lexicographically largest repeatLimitedString possible so we return "zzcccac".
Note that the string "zzcccca" is lexicographically larger but the letter 'c' appears more than 3 times in a row, so it is not a valid repeatLimitedString.

Example 2:

Input: s = "aababab", repeatLimit = 2
Output: "bbabaa"
Explanation: We use only some of the characters from s to construct the repeatLimitedString "bbabaa". 
The letter 'a' appears at most 2 times in a row.
The letter 'b' appears at most 2 times in a row.
Hence, no letter appears more than repeatLimit times in a row and the string is a valid repeatLimitedString.
The string is the lexicographically largest repeatLimitedString possible so we return "bbabaa".
Note that the string "bbabaaa" is lexicographically larger but the letter 'a' appears more than 2 times in a row, so it is not a valid repeatLimitedString.

 

Constraints:

  • 1 <= repeatLimit <= s.length <= 105
  • s consists of lowercase English letters.

Solutions

Solution 1: Greedy Algorithm

First, we use an array $cnt$ of length $26$ to count the number of occurrences of each character in string $s$. Then, we enumerate the $i$th letter of the alphabet in descending order, each time taking out at most $\min(cnt[i], repeatLimit)$ of letter $i$. If after taking them out $cnt[i]$ is still greater than $0$, we continue to take the $j$th letter of the alphabet, where $j$ is the largest index satisfying $j < i$ and $cnt[j] > 0$, until all letters are taken.

The time complexity is $O(n + |\Sigma|)$, and the space complexity is $O(|\Sigma|)$. Here, $n$ is the length of string $s$, and $\Sigma$ is the character set. In this problem, $|\Sigma| = 26$.

class Solution:
  def repeatLimitedString(self, s: str, repeatLimit: int) -> str:
    cnt = [0] * 26
    for c in s:
      cnt[ord(c) - ord("a")] += 1
    ans = []
    j = 24
    for i in range(25, -1, -1):
      j = min(i - 1, j)
      while 1:
        x = min(repeatLimit, cnt[i])
        cnt[i] -= x
        ans.append(ascii_lowercase[i] * x)
        if cnt[i] == 0:
          break
        while j >= 0 and cnt[j] == 0:
          j -= 1
        if j < 0:
          break
        cnt[j] -= 1
        ans.append(ascii_lowercase[j])
    return "".join(ans)
class Solution {
  public String repeatLimitedString(String s, int repeatLimit) {
    int[] cnt = new int[26];
    for (int i = 0; i < s.length(); ++i) {
      ++cnt[s.charAt(i) - 'a'];
    }
    StringBuilder ans = new StringBuilder();
    for (int i = 25, j = 24; i >= 0; --i) {
      j = Math.min(j, i - 1);
      while (true) {
        for (int k = Math.min(cnt[i], repeatLimit); k > 0; --k) {
          ans.append((char) ('a' + i));
          --cnt[i];
        }
        if (cnt[i] == 0) {
          break;
        }
        while (j >= 0 && cnt[j] == 0) {
          --j;
        }
        if (j < 0) {
          break;
        }
        ans.append((char) ('a' + j));
        --cnt[j];
      }
    }
    return ans.toString();
  }
}
class Solution {
public:
  string repeatLimitedString(string s, int repeatLimit) {
    int cnt[26]{};
    for (char& c : s) {
      ++cnt[c - 'a'];
    }
    string ans;
    for (int i = 25, j = 24; ~i; --i) {
      j = min(j, i - 1);
      while (1) {
        for (int k = min(cnt[i], repeatLimit); k; --k) {
          ans += 'a' + i;
          --cnt[i];
        }
        if (cnt[i] == 0) {
          break;
        }
        while (j >= 0 && cnt[j] == 0) {
          --j;
        }
        if (j < 0) {
          break;
        }
        ans += 'a' + j;
        --cnt[j];
      }
    }
    return ans;
  }
};
func repeatLimitedString(s string, repeatLimit int) string {
  cnt := [26]int{}
  for _, c := range s {
    cnt[c-'a']++
  }
  var ans []byte
  for i, j := 25, 24; i >= 0; i-- {
    j = min(j, i-1)
    for {
      for k := min(cnt[i], repeatLimit); k > 0; k-- {
        ans = append(ans, byte(i+'a'))
        cnt[i]--
      }
      if cnt[i] == 0 {
        break
      }
      for j >= 0 && cnt[j] == 0 {
        j--
      }
      if j < 0 {
        break
      }
      ans = append(ans, byte(j+'a'))
      cnt[j]--
    }
  }
  return string(ans)
}
function repeatLimitedString(s: string, repeatLimit: number): string {
  const cnt: number[] = Array(26).fill(0);
  for (const c of s) {
    cnt[c.charCodeAt(0) - 97]++;
  }
  const ans: string[] = [];
  for (let i = 25, j = 24; ~i; --i) {
    j = Math.min(j, i - 1);
    while (true) {
      for (let k = Math.min(cnt[i], repeatLimit); k; --k) {
        ans.push(String.fromCharCode(97 + i));
        --cnt[i];
      }
      if (!cnt[i]) {
        break;
      }
      while (j >= 0 && !cnt[j]) {
        --j;
      }
      if (j < 0) {
        break;
      }
      ans.push(String.fromCharCode(97 + j));
      --cnt[j];
    }
  }
  return ans.join('');
}

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

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

发布评论

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