838. 推多米诺

n 张多米诺骨牌排成一行,将每张多米诺骨牌垂直竖立。在开始时,同时把一些多米诺骨牌向左或向右推。

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

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

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

给你一个字符串 dominoes 表示这一行多米诺骨牌的初始状态,其中:

dominoes[i] = 'L',表示第 i 张多米诺骨牌被推向左侧,
dominoes[i] = 'R',表示第 i 张多米诺骨牌被推向右侧,
dominoes[i] = '.',表示没有推动第 i 张多米诺骨牌。
返回表示最终状态的字符串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/push-dominoes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

模拟(一)

import java.util.Scanner;

class Solution {
    /**
     * .L.R...LR..L..
     * LL.RR.LLRRLL..
     */
    public String pushDominoes(String dominoes) {
        if (dominoes == null || dominoes.length() == 0) {
            return dominoes;
        }
        int[] left = new int[dominoes.length()];
        int[] right = new int[dominoes.length()];
        for (int i = 0; i < dominoes.length(); ++i) {
            if (dominoes.charAt(i) == 'L') {
                right[i] = 0;
            } else if (dominoes.charAt(i) == 'R') {
                right[i] = 1;
            } else {
                if (i == 0 || right[i - 1] == 0) {
                    right[i] = 0;
                } else {
                    right[i] = right[i - 1] + 1;
                }
            }
        }
        for (int i = dominoes.length() - 1; i >= 0; --i) {
            if (dominoes.charAt(i) == 'R') {
                left[i] = 0;
            } else if (dominoes.charAt(i) == 'L') {
                left[i] = 1;
            } else {
                if (i == dominoes.length() - 1 || left[i + 1] == 0) {
                    left[i] = 0;
                } else {
                    left[i] = left[i + 1] + 1;
                }
            }
        }
        char[] ans = new char[dominoes.length()];
        for (int i = 0; i < ans.length; ++i) {
            if (left[i] == right[i]) {
                ans[i] = '.';
            } else if (left[i] == 0 && right[i] != 0) {
                ans[i] = 'R';
            } else if (right[i] == 0 && left[i] != 0) {
                ans[i] = 'L';
            } else {
                if (left[i] > right[i]) {
                    ans[i] = 'R';
                } else {
                    ans[i] = 'L';
                }
            }
        }

        return new String(ans);
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            System.out.println(new Solution().pushDominoes(in.next()));
        }
    }
}

BFS

import java.util.*;

class Solution {
    public String pushDominoes(String dominoes) {
        int n = dominoes.length();
        Deque<Integer> queue = new ArrayDeque<>();
        int[] time = new int[n];
        Arrays.fill(time, -1);
        List<Character>[] force = new List[n];
        for (int i = 0; i < n; i++) {
            force[i] = new ArrayList<>();
        }
        for (int i = 0; i < n; i++) {
            char f = dominoes.charAt(i);
            if (f != '.') {
                queue.offer(i);
                time[i] = 0;
                force[i].add(f);
            }
        }

        char[] res = new char[n];
        Arrays.fill(res, '.');
        while (!queue.isEmpty()) {
            int i = queue.poll();
            if (force[i].size() == 1) {
                char f = force[i].get(0);
                res[i] = f;
                int ni = f == 'L' ? i - 1 : i + 1;
                if (ni >= 0 && ni < n) {
                    if (time[ni] == -1) {
                        queue.offer(ni);
                        time[ni] = time[i] + 1;
                        force[ni].add(f);
                    } else if (time[ni] == time[i] + 1) {
                        force[ni].add(f);
                    }
                }
            }
        }
        return new String(res);
    }
}

双指针

class Solution {
    public String pushDominoes(String dominoes) {
        char[] s = dominoes.toCharArray();
        int n = s.length, i = 0;
        char left = 'L';
        while (i < n) {
            int j = i;
            while (j < n && s[j] == '.') { // 找到一段连续的没有被推动的骨牌
                j++;
            }
            char right = j < n ? s[j] : 'R';
            if (left == right) { // 方向相同,那么这些竖立骨牌也会倒向同一方向
                while (i < j) {
                    s[i++] = right;
                }
            } else if (left == 'R' && right == 'L') { // 方向相对,那么就从两侧向中间倒
                int k = j - 1;
                while (i < k) {
                    s[i++] = 'R';
                    s[k--] = 'L';
                }
            }
            left = right;
            i = j + 1;
        }
        return new String(s);
    }
}
posted @   Tianyiya  阅读(47)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示