[LC]推多米诺

145 阅读2分钟

这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战

题目

838. 推多米诺 - 力扣(LeetCode) (leetcode-cn.com)

解析

按照题目所给的条件,如果入参中,指定了位置i一定往左倒,那么位置i就一定是往左倒。

从这里可以看出一个条件(或者说一个假定条件):

  • 某个不被拨动的牌,受到的力没有大小之分,只有方向之分。

也就是说,如果某个牌左右均受力且自身没有被拨动,那么无论左边倒了多少牌右边倒了多少牌,这个牌就是没有被拨动的。

现在所有条件都给足了,来看看如何解决这个问题。

仔细看这个问题,可以发现:

  • 位置i的状态,由:

    • i-1是否往右倒
    • i+1是否往左倒
    • 自身的拨动情况

    来共同决定。

而i-1和i+1的情况,就得由这个i左边最近的往右倒的,和i+1右边最近的往左倒的来决定。

那么,可以按照给定的顺序来进行模拟:

  • 如果遇到了一个R:
    • 如果上一个R没有遇到一个L,说明上一个R到当前的R之间,都要被推向R。
    • 否则,更新R。
  • 如果遇到了一个L:
    • 如果之前所有的R都被消除了,那么:从消除的地方到当前的L,都是L。
    • 如果之前有没有被消除的R,那么:从那个R到当前的L,一个一个地推。
  • 如果遇到了.:继续,不做任何操作。

到最后,如果还有R没有被消除,那么从那个R开始到最后,全部都变成R。

根据这个思路,可以拟出以下代码:

public String pushDominoes(String dominoes) {
    char[] status = new char[dominoes.length()];
    //左倒的
    int lp = -1;
    //右倒的
    int rp = -1;
    boolean findR = false;
    //核心思路是:找到一个往右倒的,就从右边找一个往左倒的
    for (int i = 0; i < dominoes.length(); i++) {

        if(dominoes.charAt(i) == 'R'){
            //往右倒--> 还是往右倒
            for(int j = rp+1;findR&&j<i;j++) status[j] = 'R';
            rp = i;
            status[i] = 'R';
            findR = true;
            continue;
        }

        if(dominoes.charAt(i) == 'L'){
            //如果形成了一个区间,那么就得往左推
            status[i] = 'L';

            //从上一次重置状态开始,没有再读取到R
            if(!findR){
                    for (int i1 = Math.max(lp, 0); i1 < i; i1++) status[i1] = 'L';
                } else {
                //两者不重合
                lp = i;
                    while (lp >= rp) {
                        if (lp == rp) status[lp] = '.';
                        else {
                            status[rp] = 'R';
                            status[lp] = 'L';
                        }
                        rp++;
                        lp--;
                    }
                }
            lp = i+1;
            rp = lp;
            findR = false;
            continue;
        }

        //.的情况不足以说明任何问题
        status[i] = '.';
    }

    //如果最后一个右倒的没有被消除
    if(findR) for (int i = rp+1; i < status.length; i++) status[i] = 'R';

    return new String(status);

}