多米诺骨牌均衡状态| 豆包MarsCode AI刷题

25 阅读3分钟

问题分析

小S的问题是模拟多米诺骨牌倒下的过程,并确定哪些骨牌最终仍然保持竖立。骨牌的状态由字符串表示:

  • L:该位置的骨牌将向左倒。
  • R:该位置的骨牌将向右倒。
  • . :该位置的骨牌初始时竖立,可能保持竖立或倒下。

需要解决的问题:

  1. 确定哪些骨牌因为左右力量平衡而保持竖立。
  2. 确定哪些骨牌因为两侧无推力而保持竖立。
  3. 模拟整个倒下过程后统计竖立骨牌的数量和位置。

具体规则:

  1. 如果骨牌是初始竖立状态(.),则需检查它的左侧和右侧是否存在推力。
  2. 若左侧存在推力(R)且右侧存在推力(L),则检查左右推力距离是否相等。
  3. 若两侧均无推力,则该骨牌保持竖立。
  4. 其余情况下,骨牌将被推倒。

代码功能

代码拆解和详细解释

def solution(n, data):
    result = []

    i = 0
    while i < n:
        # 如果当前是竖立的骨牌
        if data[i] == '.':
            # 看前后是否有力量平衡
            left = i - 1
            right = i + 1

            # 检查左边有无推向它的骨牌
            while left >= 0 and data[left] == '.':
                left -= 1

            # 检查右边有无推向它的骨牌
            while right < n and data[right] == '.':
                right += 1

            # 如果左右力量平衡,则该骨牌保持竖立
            if (left >= 0 and data[left] == 'R') and (right < n and data[right] == 'L'):
                # 只在 R 和 L 之间的竖立骨牌平衡
                if right - i == i - left:
                    result.append(i + 1)
            elif (left < 0 or data[left] != 'R') and (right >= n or data[right] != 'L'):
                # 左右没有推向它的力量
                result.append(i + 1)

        i += 1

    # 返回结果
    if len(result) == 0:
        return "0"
    else:
        return f"{len(result)}:" + ",".join(map(str, result))


# 测试用例
if __name__ == "__main__":
    # 你可以添加更多测试用例
    print(solution(14, ".L.R...LR..L..") == "4:3,6,13,14")  # 应输出 True
    print(solution(5, "R....") == "0")  # 应输出 True
    print(solution(1, ".") == "1:1")  # 应输出 True

核心逻辑:

  1. 遍历字符串中的每一个骨牌:

    • 如果骨牌是LR,不需要进一步处理。
    • 如果骨牌是.,需要判断其是否受到左右推力影响。
  2. 通过循环检查左侧和右侧的最近非竖立骨牌。

    • 左推力来自最近的R
    • 右推力来自最近的L
  3. 判断左右推力是否平衡:

    • 若左侧为R,右侧为L,且两侧距离相等,则该骨牌保持竖立。
    • 若左右两侧均无推力,则该骨牌保持竖立。
  4. 将符合条件的骨牌位置记录在结果列表中。

结果构造:

  • 若没有骨牌保持竖立,则返回"0"
  • 若有骨牌保持竖立,则返回竖立骨牌的数量和对应位置,格式为数量:位置1,位置2,...

测试用例分析

# 测试用例 1
print(solution(14, ".L.R...LR..L..") == "4:3,6,13,14")
  • 初始状态:.L.R...LR..L..

  • 模拟过程:

    • 第 3 个骨牌:左侧最近为L,右侧最近为R,距离相等,因此保持竖立。
    • 第 6 个骨牌:两侧无推力,因此保持竖立。
    • 第 13、14 个骨牌:两侧无推力,因此保持竖立。
  • 最终结果:4 个骨牌保持竖立,位置为3, 6, 13, 14

性能分析

  1. 时间复杂度

    • 遍历每个骨牌需要O(n)
    • 对于每个竖立骨牌,向左右查找最近的推力骨牌需要O(n)(最坏情况)。
    • 因此,总时间复杂度为O(n^2)
  2. 空间复杂度

    • 使用了一个结果列表存储竖立骨牌的位置,空间复杂度为O(k),其中k为保持竖立的骨牌数量。

对于输入规模适中的问题(如n <= 10^4),该解法是可以接受的。