返回

以简单的技巧轻松解决Leetcode-推多米诺问题

后端

LeetCode的推多米诺问题是一个经典的模拟题。给定一个由“L”、“R”和“.”组成的字符串,代表多米诺骨牌的初始状态,L表示向左倒,R表示向右倒,.表示站立。我们要模拟多米诺骨牌的倒塌过程,直到它们全部倒下或达到稳定状态。

解决此问题的关键在于识别出那些会倒塌的骨牌。在每一步模拟中,我们从左到右遍历骨牌。如果遇到一个L骨牌,它会将右边的所有骨牌推倒,直到遇到一个R骨牌或字符串的末尾。同样,如果遇到一个R骨牌,它会将左边的所有骨牌推倒,直到遇到一个L骨牌或字符串的开头。

经过一次模拟后,我们将得到一个新的骨牌状态。我们将继续模拟,直到骨牌状态不再改变。最终得到的骨牌状态就是问题的解。

以下是使用Python编写的解决方案:

def push_dominoes(dominoes):
    """
    模拟多米诺骨牌的倒塌过程。

    Args:
        dominoes: 一个由“L”、“R”和“.”组成的字符串,代表多米诺骨牌的初始状态。

    Returns:
        一个由“L”、“R”和“.”组成的字符串,代表多米诺骨牌的最终状态。
    """

    # 将字符串转换为列表,以便于修改。
    dominoes = list(dominoes)

    # 循环模拟,直到骨牌状态不再改变。
    while True:
        # 保存上一次模拟的结果。
        prev_dominoes = dominoes.copy()

        # 从左到右遍历骨牌。
        for i in range(len(dominoes)):
            # 如果遇到一个L骨牌。
            if dominoes[i] == "L":
                # 将右边的所有骨牌推倒。
                for j in range(i + 1, len(dominoes)):
                    if dominoes[j] == ".":
                        dominoes[j] = "L"
                    elif dominoes[j] == "R":
                        break

            # 如果遇到一个R骨牌。
            elif dominoes[i] == "R":
                # 将左边的所有骨牌推倒。
                for j in range(i - 1, -1, -1):
                    if dominoes[j] == ".":
                        dominoes[j] = "R"
                    elif dominoes[j] == "L":
                        break

        # 如果骨牌状态不再改变,则结束模拟。
        if dominoes == prev_dominoes:
            break

    # 将列表转换为字符串,并返回。
    return "".join(dominoes)


if __name__ == "__main__":
    # 测试用例。
    test_cases = ["RR.L", "L.R.R.", ".L.R..L.", "R..L..RR"]

    # 运行测试用例。
    for test_case in test_cases:
        print(f"初始状态:{test_case}")
        print(f"最终状态:{push_dominoes(test_case)}")

该解决方案的时间复杂度为O(n^2),其中n是骨牌的数量。