问题描述
小S玩起了多米诺骨牌,他排列了一行骨牌,并可能将某些骨牌向左或向右推倒。随着骨牌连锁反应的进行,一些骨牌可能因为左右两侧受力平衡而保持竖立。现在小S想要知道在所有动作完成后,哪些骨牌保持竖立。
给定一个表示骨牌初始状态的字符串,其中:
- "L" 表示该位置的骨牌将向左倒。
- "R" 表示该位置的骨牌将向右倒。
- "." 表示该位置的骨牌初始时保持竖立。
模拟整个骨牌倒下的过程,求出最终仍然保持竖立的骨牌的数目和位置。
测试样例
样例1:
输入:
num = 14,data = ".L.R...LR..L.."
输出:'4:3,6,13,14'
样例2:
输入:
num = 5,data = "R...."
输出:'0'
样例3:
输入:
num = 1,data = "."
输出:'1:1'
这个问题可以通过模拟多米诺骨牌的倒下过程来解决。我们需要考虑两个主要因素:
- 左推与右推的影响:
L表示向左推倒,R表示向右推倒。它们会影响周围的骨牌,直到没有更多的骨牌受到影响。 - 左右受力平衡:如果一个骨牌同时受到来自左侧和右侧的推力,我们需要根据两侧的力量平衡来决定它是否倒下。如果某个骨牌只受到单边的推力(如右侧或左侧),它会倒向那一侧。如果两侧的推力在时间上是平衡的,它会保持竖立。
解题思路:
- 模拟骨牌倒下的过程:遍历整个字符串,通过两个方向的推力传播更新每个骨牌的状态。使用两个数组来记录从左向右推的影响和从右向左推的影响。
- 保持竖立的骨牌:对于每个骨牌,如果它既没有被右侧推倒,也没有被左侧推倒,它就保持竖立。
步骤:
- 从左到右遍历,计算从左侧推到当前骨牌的影响。
- 从右到左遍历,计算从右侧推到当前骨牌的影响。
- 检查每个骨牌是否保持竖立。如果骨牌既没有被左侧影响,也没有被右侧影响,则它保持竖立。
代码实现:
def solution(num, data):
# 初始化两个数组来表示左右方向的影响时间
left_force = [-1] * num # -1表示没有被影响,其他值表示倒下的时间
right_force = [-1] * num # 同上
# 从左到右遍历,记录每个骨牌被右侧推倒的影响
time = -1 # 用来记录右侧影响的时间
for i in range(num):
if data[i] == 'R':
time = 0
elif data[i] == 'L':
time = -1
if time >= 0:
right_force[i] = time
time += 1 # 影响时间逐渐递增
# 从右到左遍历,记录每个骨牌被左侧推倒的影响
time = -1 # 用来记录左侧影响的时间
for i in range(num-1, -1, -1):
if data[i] == 'L':
time = 0
elif data[i] == 'R':
time = -1
if time >= 0:
left_force[i] = time
time += 1 # 影响时间逐渐递增
# 判断哪些骨牌保持竖立
standing = []
for i in range(num):
if data[i] == '.' and right_force[i] == -1 and left_force[i] == -1:
standing.append(i + 1) # 记录竖立的骨牌位置,注意要加1
# 如果没有竖立的骨牌,返回0
if not standing:
return "0"
# 返回竖立骨牌的数量和位置
return f"{len(standing)}:{','.join(map(str, standing))}"
# 测试代码
if __name__ == "__main__":
print(solution(14, ".L.R...LR..L..") == "4:3,6,13,14")
print(solution(5, "R....") == "0")
print(solution(1, ".") == "1:1")
解释:
-
数组
left_force和right_force:right_force[i]表示从左到右传播的推力影响,如果骨牌i受到右推影响,则right_force[i]存储推力的时间,时间值递增。left_force[i]表示从右到左传播的推力影响,处理方式类似。
-
两次遍历:
- 第一次从左到右遍历,记录右侧推力的影响。
- 第二次从右到左遍历,记录左侧推力的影响。
-
判断竖立的骨牌:
- 对于每个位置
i,如果data[i]是.(竖立的骨牌),并且right_force[i]和left_force[i]都没有受到影响(即值为-1),则说明该骨牌保持竖立。
- 对于每个位置
-
返回结果:
- 如果有竖立的骨牌,返回它们的数量和位置;如果没有,则返回
0。
- 如果有竖立的骨牌,返回它们的数量和位置;如果没有,则返回