LeetCode 838
推多米诺
一行中有 N 张多米诺骨牌,我们将每张多米诺骨牌垂直竖立。
在开始时,我们同时把一些多米诺骨牌向左或向右推。
每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。
同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。
如果同时有多米诺骨牌落在一张垂直竖立的多米诺骨牌的两边,由于受力平衡, 该骨牌仍然保持不变。
就这个问题而言,我们会认为正在下降的多米诺骨牌不会对其它正在下降或已经下降的多米诺骨牌施加额外的力。
给定表示初始状态的字符串 “S” 。如果第 i 张多米诺骨牌被推向左边,则 S[i] = ‘L’;如果第 i 张多米诺骨牌被推向右边,则 S[i] = ‘R’;如果第 i 张多米诺骨牌没有被推动,则 S[i] = ‘.’。
示例 1:
输入:".L.R...LR..L.."
输出:"LL.RR.LLRRLL.."
示例 2:
输入:"RR.L"
输出:"RR.L"
说明:第一张多米诺骨牌没有给第二张施加额外的力。
解法:相邻标记
解题思路:
我们假设每一个’.‘都是被包在’L’,'R’之间,那么就有以下的情况:
- 如果我们有 “A…B”,当 A = B,那么就变成 “AAAAAA”。
- 如果我们有 “R…L”,那么结果会变成 “RRRLLL” 或者 “RRR.LLL” 如果点的个数是奇数。如果初始标记的坐标是 i 和 j,我们可以检查距离 k-i 和 j-k 来决定位置 k 的形态是 ‘L’,‘R’ 还是 ‘.’。
- 如果我们有 “L…R”,就什么都不做,跳过。
代码如下:
class Solution {
public String pushDominoes(String dominoes) {
int N = dominoes.length();
int[] indexes = new int[N+2];
char[] symbols = new char[N+2];
int len = 1;
indexes[0] = -1;
symbols[0] = 'L'; //左边界,主要是为了使第一个元素也能被'L','R'包起
for (int i = 0; i < N; ++i)
if (dominoes.charAt(i) != '.')
{
indexes[len] = i;
symbols[len++] = dominoes.charAt(i);
}
indexes[len] = N;
symbols[len++] = 'R'; //同理
char[] ans = dominoes.toCharArray();
for (int index = 0; index < len - 1; ++index) //遍历每一对'L','R'
{
int i = indexes[index], j = indexes[index+1];
char x = symbols[index], y = symbols[index+1];
char write;
if (x == y)
{
for (int k = i+1; k < j; ++k)
ans[k] = x;
}
else if (x > y)
{ // RL
for (int k = i+1; k < j; ++k)
ans[k] = k-i == j-k ? '.' : k-i < j-k ? 'R' : 'L';
}
}
return String.valueOf(ans);
}
}
解法来源
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/push-dominoes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。