n 张多米诺骨牌排成一行,将每张多米诺骨牌垂直竖立。在开始时,同时把一些多米诺骨牌向左或向右推。每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。如果一张垂直竖立的多米诺骨牌的两侧同时有多米诺骨牌倒下时,由于受力平衡, 该骨牌仍然保持不变。就这个问题而言,我们会认为一张正在倒下的多米诺骨牌不会对其它正在倒下或已经倒下的多米诺骨牌施加额外的力。给你一个字符串 dominoes 表示这一行多米诺骨牌的初始状态,其中:dominoes[i] = ‘L’,表示第 i 张多米诺骨牌被推向左侧,dominoes[i] = ‘R’,表示第 i 张多米诺骨牌被推向右侧,dominoes[i] = ‘.’,表示没有推动第 i 张多米诺骨牌。返回表示最终状态的字符串。
示例 1:
输入:dominoes = “RR.L”
输出:“RR.L”
解释:第一张多米诺骨牌没有给第二张施加额外的力。
示例 2:
输入:dominoes = “.L.R…LR…L…”
输出:“LL.RR.LLRRLL…”
思路:因为推倒骨牌是一个行为传导的行为,因此可以使用广搜。先将所有不为 ’ . ’ 的字符入队。队列存储的内容为:字符位置、修改时间、字符推动的方向。当有 ’ . ’ 左右都受力的时候,需要将骨牌恢复到竖直状态
class Solution {
public String pushDominoes(String dominoes) {
char[] dmn = dominoes.toCharArray();
int len = dmn.length;
int[] recordTime = new int[len];
Deque<int[]> queue = new LinkedList<>();
for(int i = 0; i < len; i++){
if(dmn[i] == '.')
continue;
int dir = dmn[i] == 'L' ? -1 : 1;
queue.add(new int[]{i,1,dir});
recordTime[i] = 1;
}
while(!queue.isEmpty()){
int[] pos = queue.pollFirst();
int loc = pos[0],time = pos[1],dir = pos[2];
int next = loc + dir;
//如果当前的字符为 ' . ' 则属于左右都受力后恢复为竖立状态,直接跳过本次循环
if(dmn[loc] == '.' || (next < 0 || next >= len))
continue;
if(recordTime[next] == 0){
queue.addLast(new int[]{next,time+1,dir});
dmn[next] = dir == -1 ? 'L' : 'R';
recordTime[next] = time + 1;
}else if(recordTime[next] == time + 1){
dmn[next] = '.';
}
}
return String.valueOf(dmn);
}
}