最小非递减子字符串成本 | 豆包MarsCode AI刷题

60 阅读2分钟

问题描述

小U有一个由字符 a 和 b 组成的字符串 S,字符串的长度为 N,字符从编号 0 到 N-1 依次排列。小U想要找到字符串 S 的“成本”,定义为:字符串中按非递减顺序排列的最长子字符串的长度。

小U可以进行最多一次操作:选择一个位置 i (0 <= i < N-1),并交换 S[i] 和 S[i+1]

你需要帮助小U计算,在执行最多一次交换操作后,字符串 S 的最小可能成本是多少。

例如:当 N = 4 且 S = "abba" 时,小U可以选择交换 S[0] 和 S[1],得到字符串 "baba"。此时字符串的成本为 2,且可以证明这是最小的可能成本。


测试样例

样例1:

输入:N = 4,S = "abba"
输出:2

样例2:

输入:N = 5,S = "baabb"
输出:2

样例3:

输入:N = 3,S = "bab"
输出:2

解题思路

1. 初始成本计算

首先,我们需要计算字符串 S 的初始成本,即不进行任何交换时的最长非递减子字符串的长度。这个可以通过遍历字符串 S,记录当前非递减子字符串的长度,并更新最大长度来实现。

2. 尝试所有可能的交换

接下来,我们尝试所有可能的交换位置 i0 <= i < N-1),交换 S[i] 和 S[i+1],生成新的字符串 swapped_S

3. 计算交换后的成本

对于每个交换后的字符串 swapped_S,我们再次计算其最长非递减子字符串的长度,即交换后的成本。

4. 更新最小成本

在所有可能的交换中,找到最小的成本,并将其作为最终结果返回。

完整代码

def solution(N: int, S: str) -> int:
    # 计算字符串 S 中最长非递减子字符串的长度
    def calculate_cost(S: str) -> int:
        max_len = 1
        current_len = 1
        for i in range(1, len(S)):
            if S[i] >= S[i-1]:  # 如果当前字符不小于前一个字符
                current_len += 1
                max_len = max(max_len, current_len)
            else:
                current_len = 1  # 重置当前非递减子字符串的长度
        return max_len
    
    # 计算初始字符串 S 的成本
    initial_cost = calculate_cost(S)
    
    # 尝试所有可能的交换位置
    min_cost = initial_cost
    for i in range(N - 1):
        # 交换 S[i] 和 S[i+1]
        swapped_S = S[:i] + S[i+1] + S[i] + S[i+2:]
        # 计算交换后的成本
        swapped_cost = calculate_cost(swapped_S)
        # 更新最小成本
        min_cost = min(min_cost, swapped_cost)
    
    return min_cost

# 测试用例
if __name__ == '__main__':
    print(solution(N = 4, S = "abba") == 2)  # 交换 "ab" -> "ba" 后,最长非递减子串是 "bb" 长度为 2
    print(solution(N = 5, S = "baabb") == 2)  # 交换 "ba" -> "ab" 后,最长非递减子串是 "aa" 长度为 2
    print(solution(N = 3, S = "bab") == 2)   # 交换 "ba" -> "ab" 后,最长非递减子串是 "ab" 或 "ba" 长度为 2