“回文博弈”题目要求
一、问题描述
小C和小U在一场激烈的回文博弈中展开对决。游戏从一个初始字符串s开始,规则如下:
- 每个玩家轮流行动,每次行动都可以重新排列字符串。
- 如果通过重新排列能够形成一个回文串,游戏立即结束,当前玩家获胜。
- 如果无法形成回文串,玩家必须删除字符串中的一个字符,游戏继续。
小C总是先手,两人都使用最优策略,最终谁将赢得这场比赛呢?如果小C获胜则输出"C",小U获胜则输出"U"
二、测试样例
样例1:
输入:
s = "aab"
输出:'C'
样例2:
输入:
s = "abc"
输出:'C'
样例3:
输入:
s = "abcd"
输出:'U'
三、题目解析
3.1代码思路
- 统计字符出现次数:使用一个长度为26的数组
count来统计每个字符的出现次数。count[c - 'a']++表示将字符c的出现次数加1。 - 计算奇数次字符个数:遍历
count数组,统计出现次数为奇数的字符个数,存储在变量oddCount中。 - 判断是否可以形成回文串:如果
oddCount小于等于1,说明可以通过重新排列形成回文串,小C直接获胜,返回'C'。 - 博弈策略:
- 如果
oddCount是奇数,小C可以通过删除一个奇数次字符,使得oddCount变为偶数,小C获胜,返回'C'。 - 如果
oddCount是偶数,小C删除一个奇数次字符后,oddCount仍然是偶数,小U仍然可以继续博弈。
3.2详细代码
public static char solution(String s) {
// 统计每个字符的出现次数
int[] count = new int[26];
for (char c : s.toCharArray()) {
count[c - 'a']++;
}
// 计算出现奇数次的字符个数
int oddCount = 0;
for (int c : count) {
if (c % 2 != 0) {
oddCount++;
}
}
// 判断是否可以形成回文串
if (oddCount <= 1) {
return 'C'; // 小C直接获胜
}
// 如果不能直接形成回文串,判断删除一个字符后的情况
// 如果 oddCount 是奇数,小C可以删除一个奇数次字符,使得 oddCount 变为偶数
// 如果 oddCount 是偶数,小C删除一个奇数次字符后,oddCount 仍然是偶数
if (oddCount % 2 == 1) {
return 'C'; // 小C获胜
} else {
return 'U'; // 小U获胜
}
}
public static void main(String[] args) {
System.out.println(solution("aab") == 'C');
System.out.println(solution("abc") == 'C');
System.out.println(solution("abcd") == 'U');
}
}
四、知识总结
博弈策略: 通过设定oddCount的大小及奇偶情况来判断胜负,具体如下:
- 如果
oddCount大于 1,我们需要进一步判断删除一个字符后的情况。 - 如果
oddCount是奇数,小C可以删除一个奇数次字符,使得oddCount变为偶数,这样小U就会面临一个更不利的情况。 - 如果
oddCount是偶数,小C删除一个奇数次字符后,oddCount仍然是偶数,小U仍然可以继续博弈。