问题描述
小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'
解题思路
- 输入解析:首先解析输入,得到骨牌的总数和初始状态的字符串。
- 从右向左遍历:记录每个位置因右侧骨牌倒下而倒下的力(使用数组
t)。如果当前骨牌是.且下一个骨牌是R或右侧已经有倒下的力传递过来,则当前骨牌也会倒下,并且其倒下的力增加1。 - 从左向右遍历:记录每个位置因左侧骨牌倒下而倒下的力(使用数组
t1)。如果当前骨牌是.且上一个骨牌是L或左侧已经有倒下的力传递过来,则当前骨牌也会倒下,并且其倒下的力减少1。 - 计算最终结果:遍历所有骨牌,如果某个骨牌初始状态是
.且左右两边的力之和为0,则该骨牌最终保持竖立。 - 输出结果:统计最终保持竖立的骨牌数量和位置,并以指定的格式输出。
Python实现
def solution(num, data):
t = [0] * num
t1 = [0] * num
str_data = list(data)
# 处理向右倒的骨牌
for i in range(1, num):
if (str_data[i - 1] == 'R' and str_data[i] == '.') or (t[i - 1] > 0 and str_data[i] == '.'):
t[i] = t[i - 1] + 1
# 处理向左倒的骨牌
for i in range(num - 2, -1, -1):
if (str_data[i + 1] == 'L' and str_data[i] == '.') or (t1[i + 1] < 0 and str_data[i] == '.'):
t1[i] = t1[i + 1] - 1
s1 = []
sum = 0
# 统计保持竖立的骨牌
for i in range(num):
if str_data[i] == '.' and t[i] + t1[i] == 0:
s1.append(str(i + 1))
sum += 1
if sum != 0:
return f"{sum}:" + ",".join(s1)
else:
return f"{sum}"
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" )
代码详解
-
初始化数组:
t = [0] * num:创建一个长度为num的数组t,用于记录从右向左每个位置骨牌因右侧骨牌倒下而受到的力(正数表示向右倒下的力)。t1 = [0] * num:创建一个长度为num的数组t1,用于记录从左向右每个位置骨牌因左侧骨牌倒下而受到的力(负数表示向左倒下的力)。str_data = list(data):将输入的字符串data转换为字符列表,方便后续按索引访问和修改。
-
处理向右倒的骨牌:
- 遍历从1到
num-1的索引i。 - 如果前一个骨牌是
R且当前骨牌是.,或者前一个位置的力t[i - 1]大于0且当前骨牌是.,则当前骨牌也会向右倒下,并且其受到的力增加(t[i] = t[i - 1] + 1)。
- 遍历从1到
-
处理向左倒的骨牌:
- 遍历从
num-2到0的索引i(倒序)。 - 如果后一个骨牌是
L且当前骨牌是.,或者后一个位置的力t1[i + 1]小于0且当前骨牌是.,则当前骨牌也会向左倒下,并且其受到的力减少(t1[i] = t1[i + 1] - 1)。
- 遍历从
-
统计保持竖立的骨牌:
- 初始化一个空列表
s1用于存储保持竖立的骨牌位置(转换为字符串格式),以及一个计数器sum用于记录保持竖立的骨牌数量。 - 遍历所有骨牌位置
i。 - 如果当前骨牌是
.且左右两边的力之和为0(t[i] + t1[i] == 0),则当前骨牌保持竖立。将其位置(i + 1,因为索引从0开始而位置从1开始)添加到列表s1中,并增加计数器sum。
- 初始化一个空列表
-
返回结果:
- 如果保持竖立的骨牌数量
sum不为0,则返回格式化的字符串,包括数量sum和用逗号分隔的保持竖立的骨牌位置列表。 - 如果保持竖立的骨牌数量
sum为0,则只返回数量sum(注意这种情况下返回的字符串末尾没有冒号和逗号)。
- 如果保持竖立的骨牌数量