当前位置: 面试刷题>> 翻转游戏 (经典算法题500道)
### 翻转游戏题目描述
**题目:翻转游戏**
给定一个由 '0' 和 '1' 组成的字符串 `s`,长度为 `n`。你可以进行如下操作:
- 选择字符串中的任意两个相邻的字符进行翻转(即 '0' 变成 '1','1' 变成 '0')。
- 目标是通过有限次翻转操作,使得字符串 `s` 中所有字符均为 '0'。
请问是否存在一种翻转方式可以达到目标?如果存在,请输出任意一种翻转序列;如果不存在,则输出 "impossible"。
**注意**:
1. 翻转操作可以多次进行,但每次只能翻转相邻的两个字符。
2. 翻转序列不需要是最短的,只需证明存在性即可。
### 示例
**输入**:s = "0101"
**输出**:"0000"(或任何可以翻转成 "0000" 的序列,例如 "flip 1", "flip 3")
**输入**:s = "1110"
**输出**:"impossible"
### 解题思路
观察题目可以发现,除了最左边的 '1' 需要通过右侧相邻的 '0' 翻转过来之外,其余的 '1' 都可以通过与其相邻的 '0' 翻转来消除。而最左侧的 '1' 如果没有右侧的 '0' 来翻转,则无法通过有限次操作将其翻转为 '0'。
因此,我们可以得出结论:如果字符串 `s` 中包含 '1' 的数量是奇数,且最左侧的字符是 '1',则无法通过翻转操作使所有字符都为 '0';否则,存在一种翻转方式。
### 示例代码
#### PHP
```php
function canFlipToZero(string $s): string {
$countOnes = substr_count($s, '1');
// 如果'1'的数量是奇数且第一个字符是'1',则无法翻转成'000...'
if ($countOnes % 2 != 0 && $s[0] == '1') {
return "impossible";
}
// 示例输出,实际不需要翻转序列,因为已经证明了存在性
return str_repeat('0', strlen($s));
}
// 测试
echo canFlipToZero("0101"); // 输出 "0000"
echo PHP_EOL;
echo canFlipToZero("1110"); // 输出 "impossible"
```
#### Python
```python
def can_flip_to_zero(s: str) -> str:
count_ones = s.count('1')
# 如果'1'的数量是奇数且第一个字符是'1',则无法翻转成'000...'
if count_ones % 2 != 0 and s[0] == '1':
return "impossible"
# 示例输出
return '0' * len(s)
# 测试
print(can_flip_to_zero("0101")) # 输出 "0000"
print(can_flip_to_zero("1110")) # 输出 "impossible"
```
#### JavaScript
```javascript
function canFlipToZero(s) {
let countOnes = 0;
for (let i = 0; i < s.length; i++) {
if (s[i] === '1') {
countOnes++;
}
// 如果'1'的数量是奇数且遇到第一个'1',直接返回"impossible"
if (countOnes % 2 !== 0 && i === 0) {
return "impossible";
}
}
// 示例输出
return '0'.repeat(s.length);
}
// 测试
console.log(canFlipToZero("0101")); // 输出 "0000"
console.log(canFlipToZero("1110")); // 输出 "impossible"
```
**码小课网站中有更多相关内容分享给大家学习**,包括但不限于算法设计、数据结构、编程技巧等,欢迎访问码小课获取更多知识。