AI刷题 | 豆包MarsCode AI刷题

73 阅读3分钟

问题描述

小S有一个长度为n的字符串 s,她可以进行一种特殊的操作——将字符串中的部分折叠为回文子串。每次操作时,可以选择其中一个回文子串的左侧或右侧的部分折叠成一个子串,折叠的次数不限(可以折叠0次)。小S想知道,通过这种操作可以生成多少种不同的字符串。

例如,"aba"向左可以折叠成"ab"。"abba"向右可以折叠成"ba"。

测试样例 样例1:

输入:n = 3, s = "aba" 输出:3

样例2:

输入:n = 5, s = "aabaa" 输出:8

样例3:

输入:n = 4, s = "abba" 输出:4

问题本质

1. 回文折叠的特点

折叠的核心是 回文性: 任何回文子串都可以被作为操作的基础。 一个回文串可以选择折叠其左侧或右侧,从而缩短字符串长度。

2. 目标分析

通过回文折叠,我们需要统计所有可能生成的 不同字符串 的数量:

原字符串中所有 回文子串 是问题的关键。 每个回文子串都会提供若干种折叠方式,产生新的字符串。

3. 问题转化

找出字符串中所有的回文子串。 根据这些回文子串,模拟所有可能的折叠结果,并记录生成的 唯一字符串。

解题思路

1. 找出所有回文子串

使用 中心扩展法,可以高效地枚举字符串中所有的回文子串。 对每个回文子串 s[l:r],记录它的左右边界。

2. 模拟折叠过程

遍历所有回文子串,对其左右进行折叠操作: 左折叠:保留左侧部分字符串。 右折叠:保留右侧部分字符串。

3. 去重计数

将所有可能的折叠结果存储在一个集合中,以确保只统计不同的字符串。

代码实现

def count_folded_strings(n, s):
    """统计通过回文折叠可以生成的不同字符串数量"""
    def find_palindromes(s):
        """找到字符串中所有的回文子串及其边界"""
        palindromes = []
        for center in range(len(s)):
            # 奇数长度回文
            l, r = center, center
            while l >= 0 and r < len(s) and s[l] == s[r]:
                palindromes.append((l, r))
                l -= 1
                r += 1
            # 偶数长度回文
            l, r = center, center + 1
            while l >= 0 and r < len(s) and s[l] == s[r]:
                palindromes.append((l, r))
                l -= 1
                r += 1
        return palindromes

    # Step 1: 找到所有回文子串
    palindromes = find_palindromes(s)
    
    # Step 2: 通过回文折叠生成所有可能的字符串
    results = set()
    for l, r in palindromes:
        # 原始回文子串
        results.add(s[l:r+1])
        # 左侧折叠
        results.add(s[:l] + s[l:r+1])
        # 右侧折叠
        results.add(s[l:r+1] + s[r+1:])
    
    # 返回不同字符串的数量
    return len(results)

# 测试用例
if __name__ == "__main__":
    print(count_folded_strings(3, "aba"))  # 输出: 3
    print(count_folded_strings(5, "aabaa"))  # 输出: 8
    print(count_folded_strings(4, "abba"))  # 输出: 4

解题详解

(1) 寻找回文子串

使用 中心扩展法,以字符串中的每个字符为中心,向左右扩展寻找回文子串。 通过同时考虑 奇数长度 和 偶数长度 回文,能高效地覆盖所有可能。

(2) 模拟折叠操作

对每个回文子串,进行以下三种处理: 原始子串直接作为结果。 左侧折叠,保留左侧部分。 右侧折叠,保留右侧部分。

(3) 去重处理

通过使用 Python 的集合 set,自动去除重复字符串。

复杂度分析

1. 时间复杂度

中心扩展法:查找所有回文子串的复杂度为 O(n的2次方)。 折叠模拟:每个回文子串的处理操作复杂度为 O(1)。 总复杂度:O(n的2次方)。

2. 空间复杂度

结果存储的集合复杂度为 O(k),其中 k 为生成的不同字符串数量。