LeetCode 838. 推多米诺

发布于 2023-06-01 14:48:24 字数 2617 浏览 70 评论 0

一行中有 N 张多米诺骨牌,我们将每张多米诺骨牌垂直竖立。

在开始时,我们同时把一些多米诺骨牌向左或向右推。

每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。

同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。

如果同时有多米诺骨牌落在一张垂直竖立的多米诺骨牌的两边,由于受力平衡, 该骨牌仍然保持不变。

就这个问题而言,我们会认为正在下降的多米诺骨牌不会对其它正在下降或已经下降的多米诺骨牌施加额外的力。

给定表示初始状态的字符串 "S" 。如果第 i 张多米诺骨牌被推向左边,则 S[i] = 'L';如果第 i 张多米诺骨牌被推向右边,则 S[i] = 'R';如果第 i 张多米诺骨牌没有被推动,则 S[i] = '.'。

返回表示最终状态的字符串。

示例 1:

输入:".L.R...LR..L.."
输出:"LL.RR.LLRRLL.."

示例 2:

输入:"RR.L"
输出:"RR.L"
说明:第一张多米诺骨牌没有给第二张施加额外的力。

提示:

0 <= N <= 10^5
表示多米诺骨牌状态的字符串只含有 'L','R'; 以及 '.';

前置知识

  • 双指针
  • 哨兵

思路

首先最终的 dominoes 状态一定满足:

  • 如果该 domino 受力了(L 或者 R),那么最终状态一定是受力的状态。比如 domino 受力为 L,那么最终状态一定也是 L,R 也是同理。
  • 如果一个 domino 没有受力,那么其可能保持原样,也可能由于其他 domino 而导致其变为 L 或者 R

因此我们只需要探究字符串 dominoes 中的 "." 在最终是 L 还是 R 即可。这里有一个关键点:只有相邻的受力 dominoes 才会相互影响。比如 .L...R..L 那么:

  • 只有第一个 L 和 R 有可能有影响
  • R 和第二个 L 有影响
  • 第一个 L 和 第二个 L 没有影响,因为二者并不相邻

想清楚这些,我们的算法就比较简单了。

我们可以使用双指针。其中:

  • 左指针指向第一个受力 domino
  • 右指针指向下一个受力 domino

左指针和右指针之前的 domino(一定是 .),最终的状态由左右指针指向而定。

具体地:

  • 如果左指针是 L,右指针是 R,那么中间保持 . 不变
  • 如果左指针是 L,右指针是 L,那么中间都是 L
  • 如果左指针是 R,右指针是 R,那么中间都是 R
  • 如果左指针是 R,右指针是 L,那么中间左半部分是 R 有右部分是 L,最中间(如果中间的 domino 个数是奇数的话)是 .

为了简化判断,可以在 domino 前放一个 L,后放一个 R。

关键点

  • 只有相邻的受力 dominoes 才会相互影响
  • 使用哨兵简化操作

代码

  • 语言支持:Python3

Python3 Code:


class Solution:
    def pushDominoes(self, dominoes: str) -> str:
        dominoes = 'L' + dominoes + 'R'
        i = 0
        j = i + 1
        ans = ''
        while j < len(dominoes):
            if dominoes[j] == '.':
                j += 1
                continue
            count = (j - i - 1)
            if i != 0 :ans += dominoes[i]
            if dominoes[i] == 'L' and dominoes[j] == 'R':
                ans += '.' * count
            elif dominoes[i] == 'L' and dominoes[j] == 'L':
                ans += 'L' * count
            elif dominoes[i] == 'R' and dominoes[j] == 'R':
                ans += 'R' * count
            elif dominoes[i] == 'R' and dominoes[j] == 'L':
                ans += 'R' * (count//2) + '.'*(count%2) + 'L' * (count//2)
            i = j
            j += 1
        return ans

复杂度分析

令 n 为数组长度。

  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(1)$

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

妖妓

暂无简介

0 文章
0 评论
520 人气
更多

推荐作者

金兰素衣

文章 0 评论 0

ゃ人海孤独症

文章 0 评论 0

一枫情书

文章 0 评论 0

清晰传感

文章 0 评论 0

mb_XvqQsWhl

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文