将字符串拆分为若干长度为 k 的组

标签: 字符串 模拟

难度: Easy

字符串 s 可以按下述步骤划分为若干长度为 k 的组:

  • 第一组由字符串中的前 k 个字符组成,第二组由接下来的 k 个字符串组成,依此类推。每个字符都能够成为 某一个 组的一部分。
  • 对于最后一组,如果字符串剩下的字符 不足 k 个,需使用字符 fill 来补全这一组字符。

注意,在去除最后一个组的填充字符 fill(如果存在的话)并按顺序连接所有的组后,所得到的字符串应该是 s

给你一个字符串 s ,以及每组的长度 k 和一个用于填充的字符 fill ,按上述步骤处理之后,返回一个字符串数组,该数组表示 s 分组后 每个组的组成情况

示例 1:

输入:s = "abcdefghi", k = 3, fill = "x"
输出:["abc","def","ghi"]
解释:
前 3 个字符是 "abc" ,形成第一组。
接下来 3 个字符是 "def" ,形成第二组。
最后 3 个字符是 "ghi" ,形成第三组。
由于所有组都可以由字符串中的字符完全填充,所以不需要使用填充字符。
因此,形成 3 组,分别是 "abc"、"def" 和 "ghi" 。

示例 2:

输入:s = "abcdefghij", k = 3, fill = "x"
输出:["abc","def","ghi","jxx"]
解释:
与前一个例子类似,形成前三组 "abc"、"def" 和 "ghi" 。
对于最后一组,字符串中仅剩下字符 'j' 可以用。为了补全这一组,使用填充字符 'x' 两次。
因此,形成 4 组,分别是 "abc"、"def"、"ghi" 和 "jxx" 。

提示:

  • 1 <= s.length <= 100
  • s 仅由小写英文字母组成
  • 1 <= k <= 100
  • fill 是一个小写英文字母

Submission

运行时间: 24 ms

内存: 16.5 MB

class Solution:
    def divideString(self, s: str, k: int, fill: str) -> List[str]:
        ret = []
        s_size = len(s)
        idx = 0
        while idx < s_size - (s_size % k):
            ret.append(s[idx : idx + k])
            idx += k
        if idx < s_size:
            last = s[idx : ]
            while len(last) < k:
                last += fill
            ret.append(last)
        return ret

Explain

该题解的核心思路是将字符串s按照长度k进行分组。首先遍历字符串,并每次截取长度为k的子串,直到剩余的字符数小于k。如果最后一组字符数不足k,则使用填充字符fill补全至k个字符。这个过程通过一个循环实现,其中,索引idx每次增加k,直到它超过了长度n减去n对k取模的结果(即s_size - (s_size % k)),这保证了idx+k不会超过字符串长度。如果最后剩余的字符数不足k,这部分字符单独处理,并用fill字符填充到k个字符。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def divideString(self, s: str, k: int, fill: str) -> List[str]:
        ret = []  # 结果列表,存储每个分组的字符串
        s_size = len(s)  # 字符串s的总长度
        idx = 0  # 初始索引
        # 处理完整的k个字符的组
        while idx < s_size - (s_size % k):
            ret.append(s[idx : idx + k])  # 添加长度为k的子串到结果列表
            idx += k  # 更新索引,移动k个位置
        # 处理最后一个不完整的组,如果有的话
        if idx < s_size:
            last = s[idx : ]  # 取剩余的字符
            while len(last) < k:
                last += fill  # 使用fill字符补全到k个字符
            ret.append(last)  # 添加处理过的最后一个组到结果列表
        return ret  # 返回结果列表

Explore

这种条件是为了确保在循环中处理的子串总是完整的,长度为k。通过计算 s_size - (s_size % k),我们实际上是找到最接近s_size的,且为k的整数倍的数。这保证了每次循环中idx的起点加上k不会超出字符串s的实际长度。因此,这种方式确保在主循环中只处理能够完全形成k长度组的部分,避免了索引超出字符串长度的风险。

在主循环中处理的是长度恰好为k的子串。如果字符串长度不是k的整数倍,那么最后将剩下少于k个字符的一段。这一段需要单独处理,因为它可能不足k长,需要填充额外的字符以达到k的长度。如果这部分也在主循环中处理,则会需要在每次循环中添加额外的条件判断,这可能会使主循环的逻辑更加复杂且效率降低。因此,将它单独处理可以简化代码并提高效率。

如果k的值大于字符串s的长度,主循环将不会执行,因为初始索引0就已经不满足小于 s_size - (s_size % k) 的条件。在这种情况下,代码将直接进入处理最后一个不完整的组的逻辑。由于整个字符串都是“不完整的组”,它将被填充至k个字符长。因此,输出结果将是一个单一的字符串,长度为k,包含原字符串s后跟足够数量的fill字符以达到长度k。题解已经考虑了这种边界情况。

原始代码假设fill是一个单一字符。如果fill是一个较长的字符串或者一个空字符串,处理逻辑应当有所调整。对于较长的fill字符串,应当只取其首个字符进行填充。如果fill是空字符串,则无法进行有效填充,这可能导致最后一个组不足k长度。在实际应用中,应当修改代码以确保fill至少包含一个字符,并且在填充时只使用fill的第一个字符,避免因填充字符串过长或为空而引起的问题。