问题描述
小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. 尝试所有可能的交换
接下来,我们尝试所有可能的交换位置 i(0 <= 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