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

66 阅读3分钟

题目理解

题目描述了一个多米诺骨牌的倒下过程,其中每个骨牌可能向左倒("L")、向右倒("R")或保持竖立(".")。我们需要模拟这个过程,并最终确定哪些骨牌在所有动作完成后仍然保持竖立。

数据结构选择

在这个问题中,我们选择使用字符串来表示骨牌的状态。字符串的每个字符代表一个骨牌的状态,初始状态由输入的字符串 data 给出。

算法步骤

  1. 初始状态处理

    • 我们首先需要处理初始状态,即字符串 data
    • 使用一个循环来模拟骨牌的倒下过程,直到状态不再变化。
  2. 状态更新

    • 在每次循环中,我们需要检查并更新骨牌的状态。

    • 具体来说,我们需要处理以下几种情况:

      • "R.L":这种情况表示中间的骨牌会被两侧的骨牌推倒,因此我们可以将其替换为 "X" 作为临时标记。
      • "R.":这种情况表示右边的骨牌会被左边的骨牌推倒,因此我们可以将其替换为 "RR"。
      • ".L":这种情况表示左边的骨牌会被右边的骨牌推倒,因此我们可以将其替换为 "LL"。
    • 最后,我们将 "X" 还原为 "R.L",因为 "X" 只是一个临时标记。

  3. 最终状态检查

    • 在所有动作完成后,我们需要检查哪些骨牌仍然保持竖立。
    • 遍历字符串 data,统计仍然保持竖立的骨牌数量,并记录它们的位置。

代码详解

def solution(num, data):
    # 初始状态处理
    pre = ""
    while pre != data:
        pre = data 
        data = data.replace("R.L", "X")  # 处理 "R.L" 情况
        data = data.replace("R.", "RR")   # 处理 "R." 情况
        data = data.replace(".L", "LL")   # 处理 ".L" 情况
        data = data.replace("X", "R.L")   # 还原 "X" 为 "R.L"

    # 最终状态检查
    num = 0
    upright_positions = []
    for i in range(len(data)):
        if data[i] == ".":
            num += 1
            upright_positions.append(i + 1)

    # 返回结果
    if num == 0:
        return str(num)
    return f"{num}:{','.join(map(str, upright_positions))}"

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")

个人思考与分析

  1. 状态更新的顺序

    • 在状态更新过程中,我们需要注意更新的顺序。例如,如果我们先处理 "R." 再处理 ".L",可能会导致错误的更新。因此,我们需要确保在每次循环中,先处理 "R.L",再处理 "R." 和 ".L"。
  2. 临时标记的使用

    • 使用 "X" 作为临时标记是一个巧妙的设计。它避免了在处理 "R.L" 时直接替换为 "R.L",从而导致无限循环。通过使用临时标记,我们可以在一次循环中完成所有必要的替换,然后再将临时标记还原。
  3. 时间复杂度分析

    • 该算法的时间复杂度主要取决于字符串的长度和状态更新的次数。在最坏情况下,每次循环都会使字符串的长度减半,因此时间复杂度为 O(n log n),其中 n 是字符串的长度。
  4. 空间复杂度分析

    • 该算法的空间复杂度为 O(n),因为我们只需要存储字符串 data 和临时变量 pre

总结

通过模拟骨牌的倒下过程,我们可以有效地解决这个问题。关键在于正确处理状态更新和使用临时标记来避免无限循环。通过合理的算法设计和实现,我们可以在较短的时间内得到最终结果。