LeetCode 838. 推多米诺题解

838. 推多米诺题解

题目来源:838. 推多米诺

2022.02.21 每日一题

每日一题专栏地址:LeetCode 每日一题题解更新中❤️💕

这道题目是多米诺骨牌,用L表示向左侧倾斜,R表示向右侧倾斜,.表示没有推动的状态,这是一个典型的多米诺骨牌效应

法一:模拟

可以想到的方法是模拟,模拟骨牌倒下的过程,一秒进行一次变化,分解多米诺骨牌的变化

会发现,我们可以先进行寻找一段没有被推动的多米诺骨牌,判断其两侧有方向的多米诺骨牌A和B

  • 如果 AB的方向相同,则AB之间未被推动的多米诺骨牌被推到的方向与AB相同
  • 如果 AB的方向相反,则AB之间未被推动的多米诺骨牌不会被推动,保持未被推动的状态
  • 如果 AB的方向相对,则AB之间未被推动的多米诺骨牌被推到的方向与AB相同,则中间的多米诺骨牌则继续保持竖直
class Solution {
public:
    string pushDominoes(string dominoes) {
        // 统计数组的长度
        int len = dominoes.size();
        // 设置 left 左侧的初始值为 ‘L’
        // right 右侧的初始值为 ‘R’
        // 因为在两边,左右两侧的初始值不会改变结果
        char left = 'L', right = 'R';
        int i = 0, j = 0;
        while (i < len) {
            j = i;
            // 遍历数组寻找到一串未翻倒的骨牌
            while (j < len && dominoes[j] == '.')
                j++;
            // 判断 j 的位置,如果 j 已经大于字符串的长度了
            // 则说明 i 的右侧都是 ‘.’ 了,直接默认‘R’
            // 如果不是则让 right 置为对应的值
            right = j < len ? dominoes[j] : 'R';

            // 接下来进行判断
            // 如果 left == right 则朝着同一方向倒去就行
            if (left == right)
                while (i < j)
                    dominoes[i++] = left;
            // 如果 left 与 right 的方向不相同
            // 则朝着不同的方向倒下
            else if (left == 'R' && right == 'L') {
                // 设计一个变量 k = j - 1 是为了令左右两端保持同步
                int k = j - 1;
                while (i < k) {
                    dominoes[i++] = left;
                    dominoes[k--] = right;
                }
            }
            // 不断更新 left 的值
            left = right;
            i = j + 1;
        }
        return dominoes;
    }
};
class Solution {
    public String pushDominoes(String dominoes) {
        char[] dominoe = dominoes.toCharArray();
        // 统计数组的长度
        int len = dominoe.length;
        // 设置 left 左侧的初始值为 ‘L’
        // right 右侧的初始值为 ‘R’
        // 因为在两边,左右两侧的初始值不会改变结果
        char left = 'L', right = 'R';
        int i = 0, j = 0;
        while (i < len) {
            j = i;
            // 遍历数组寻找到一串未翻倒的骨牌
            while (j < len && dominoe[j] == '.') j++;
            // 判断 j 的位置,如果 j 已经大于字符串的长度了
            // 则说明 i 的右侧都是 ‘.’ 了,直接默认‘R’
            // 如果不是则让 right 置为对应的值
            right = j < len ? dominoe[j] : 'R';

            // 接下来进行判断
            // 如果 left == right 则朝着同一方向倒去就行
            if (left == right) while (i < j) dominoe[i++] = left;
                // 如果 left 与 right 的方向不相同
                // 则朝着不同的方向倒下
            else if (left == 'R' && right == 'L') {
                // 设计一个变量 k = j - 1 是为了令左右两端保持同步
                int k = j - 1;
                while (i < k) {
                    dominoe[i++] = left;
                    dominoe[k--] = right;
                }
            }
            // 不断更新 left 的值
            left = right;
            i = j + 1;
        }
        return new String(dominoe;
    }
}
  • 时间复杂度 O ( n ) O(n) O(n)
  • 空间复杂度 O ( 1 ) O(1) O(1)[C++] / O ( n ) O(n) O(n)[Java]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值