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);
}
}
心之所向,素履以往 生如逆旅,一苇以航
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理