问题描述
小C和小U在一场激烈的回文博弈中展开对决。游戏从一个初始字符串s开始,规则如下:
- 每个玩家轮流行动,每次行动都可以重新排列字符串。
- 如果通过重新排列能够形成一个回文串,游戏立即结束,当前玩家获胜。
- 如果无法形成回文串,玩家必须删除字符串中的一个字符,游戏继续。
小C总是先手,两人都使用最优策略,最终谁将赢得这场比赛呢?如果小C获胜则输出"C",小U获胜则输出"U"
测试样例
样例1:
输入:
s = "aab"
输出:'C'
样例2:
输入:
s = "abc"
输出:'C'
样例3:
输入:
s = "abcd"
输出:'U'
问题理解
-
回文串的特性:
- 回文串是指正读和反读都相同的字符串。
- 要形成一个回文串,字符串中最多只能有一个字符出现奇数次,其余字符必须出现偶数次。
-
游戏规则:
- 小C和小U轮流行动。
- 每次行动可以重新排列字符串。
- 如果通过重新排列能形成回文串,当前玩家获胜。
- 如果不能形成回文串,玩家必须删除一个字符,游戏继续。
数据结构选择
- 使用字典(或计数器)来统计字符串中每个字符的出现次数。
算法步骤
-
统计字符出现次数:
- 遍历字符串,统计每个字符的出现次数。
-
判断能否形成回文串:
- 计算出现奇数次的字符数量。
- 如果奇数次字符的数量为0或1,当前玩家可以通过重新排列形成回文串,获胜。
-
决定胜负:
- 如果奇数次字符的数量为0或1,小C玩家获胜。
- 如果奇数次字符的数量大于1,当前玩家必须删除一个字符,游戏继续。
- 由于小C先手,如果奇数次字符的数量为奇数(大于0),小C可以通过删除一个字符使奇数次字符数量变为1,从而获胜。
- 如果奇数次字符的数量为偶数,小U可以通过删除一个字符使奇数次字符数量变为1,从而获胜。
结论
- 如果奇数次字符的数量为偶数,小C获胜。
- 如果奇数次字符的数量为奇数或奇数数量为0,小U获胜。
def solution(s: str) -> str:
# 统计每个字符的出现次数
char_count = {}
for char in s:
if char in char_count:
char_count[char] += 1
else:
char_count[char] = 1
# 计算出现奇数次的字符数量
odd_count = 0
for count in char_count.values():
if count % 2 != 0:
odd_count += 1
# 判断胜负
if odd_count %2 ==1 :
return 'C'
elif odd_count == 0:
return 'C'
else:
return 'U'
if __name__ == '__main__':
print(solution("aab") == 'C') # 应该输出 True
print(solution("abc") == 'C') # 应该输出 True
print(solution("abcd") == 'U') # 应该输出 True
代码解释
-
统计字符出现次数:
- 使用字典
char_count来记录每个字符的出现次数。 - 遍历字符串
s,对于每个字符,如果已经在字典中,则增加其计数;否则,初始化计数为1。
- 使用字典
-
计算出现奇数次的字符数量:
- 初始化
odd_count为0。 - 遍历字典
char_count的值,如果某个字符的出现次数是奇数,则增加odd_count。
- 初始化
-
判断胜负:
- 如果
odd_count为偶数或为0,小C获胜,返回'C'。 - 如果
odd_count为奇数,小U获胜,返回'U'。
- 如果
样例测试
solution("aab"):字符出现次数为{'a': 2, 'b': 1},奇数次字符数量为1,小C获胜。solution("abc"):字符出现次数为{'a': 1, 'b': 1, 'c': 1},奇数次字符数量为3,小C获胜。solution("abcd"):字符出现次数为{'a': 1, 'b': 1, 'c': 1, 'd': 1},奇数次字符数量为4,小U获胜。