「这是我参与2022首次更文挑战的第34天,活动详情查看:2022首次更文挑战」。
题目
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.."
思路
这个题目有点意思,可能一步步模拟下去应该可以做,只要连续2s的状态一致,就是结束。
不过找到关键点的话,可以简化一些。首先,一开始给出LR的,就是最终状态,所以,我们要求解的,就是当前是'.'的最终状态。
连续的一段'.',它们的最终状态,只跟左右最相邻的L或者R有关。 明白了这一点,接下来就是看这几种情况:
- left == right,无论是L还是R,那么中间的'.',最终都会变成left
- left <> right,这时候又分2种情况:
-
- left = 'L', right = 'R',这时候是往2边倒的,所以中间的'.'最终还是'.'
-
- left = 'R', right = 'L',这时候是往中间倒的,那么左边一半最终是R,右边一半最终是L,注意如果是奇数个,最中间是'.'
另外,为了处理边界方便,使得每个连续的'.'小块左右一定存在倒下的多米诺骨牌,我们给原始数组左边添加一个L,右边添加一个R,这时不会影响最后的结果,注意最后不要把这2个虚拟的添加到结果中去即可。
Java版本代码
class Solution {
public String pushDominoes(String dominoes) {
StringBuilder ans = new StringBuilder();
char left = 'L';
int indexLeft = -1;
for (int i = 0; i <= dominoes.length(); i++) {
char right;
if (i < dominoes.length()) {
right = dominoes.charAt(i);
} else {
right = 'R';
}
if (right == '.') {
continue;
}
if (left == right) {
for (int j = indexLeft+1; j < i; j++) {
ans.append(left);
}
} else if (left == 'L' && right == 'R') {
for (int j = indexLeft+1; j < i; j++) {
ans.append('.');
}
} else {
int begin = indexLeft + 1;
int end = i - 1;
int len = end - begin + 1;
for (int j = 0; j < len/2; j++) {
ans.append('R');
}
if (len%2 == 1) {
ans.append('.');
}
for (int j = 0; j < len/2; j++) {
ans.append('L');
}
}
if (i != dominoes.length()) {
ans.append(right);
}
left = right;
indexLeft = i;
}
return ans.toString();
}
}