There are n
dominoes in a line, and we place each domino vertically upright. In the beginning, we simultaneously push some of the dominoes either to the left or to the right.
After each second, each domino that is falling to the left pushes the adjacent domino on the left. Similarly, the dominoes falling to the right push their adjacent dominoes standing on the right.
When a vertical domino has dominoes falling on it from both sides, it stays still due to the balance of the forces.
For the purposes of this question, we will consider that a falling domino expends no additional force to a falling or already fallen domino.
You are given a string dominoes
representing the initial state where:
dominoes[i] = 'L'
, if theith
domino has been pushed to the left,dominoes[i] = 'R'
, if theith
domino has been pushed to the right, anddominoes[i] = '.'
, if theith
domino has not been pushed.
Return a string representing the final state.
Example 1:
Input: dominoes = "RR.L" Output: "RR.L" Explanation: The first domino expends no additional force on the second domino.
Example 2:
Input: dominoes = ".L.R...LR..L.." Output: "LL.RR.LLRRLL.."
Constraints:
n == dominoes.length
1 <= n <= 105
dominoes[i]
is either'L'
,'R'
, or'.'
.
题目链接:https://leetcode.com/problems/push-dominoes/
题目大意:同时给一组多米诺骨牌若干个向左或向右的推力,两个相同方向的力不会叠加,相反方向的力遇到会抵消,求最终的牌面
题目分析:记录每个给推力的点会影响到的连续的左边或右边的骨牌数即可,详细见注释
19ms,时间击败84.12%
class Solution {
class FallInfo {
int pos, len, dir; // 0 -> left, 1 -> right
FallInfo(int p, int l, int d) {
this.pos = p;
this.len = l;
this.dir = d;
}
}
public String pushDominoes(String dominoes) {
char[] s = dominoes.toCharArray();
int cur = 0, rpos = -1, lpos = -1, n = s.length, cnt = 0;
FallInfo[] falls = new FallInfo[n];
boolean[] vis = new boolean[n];
while (cur < n) {
if (s[cur] == 'L') {
if (rpos == -1) {
// 第一个L且左边没有R
falls[cnt++] = new FallInfo(cur, cur, 0);
} else if (rpos < cur) {
if (!vis[rpos]) {
// 当前的R只受到其右边第一个L的力的影响,最终会结果是一半R,一半L
vis[rpos] = true;
int len = (cur - rpos + 1) / 2 - 1;
falls[cnt++] = new FallInfo(rpos, len, 1);
falls[cnt++] = new FallInfo(cur, len, 0);
} else {
// 两个相邻的L之间都是L
falls[cnt++] = new FallInfo(cur, cur - lpos - 1, 0);
}
}
lpos = cur;
} else if (s[cur] == 'R') {
if (rpos > lpos) {
// 两个相邻的R之间都是R
falls[cnt++] = new FallInfo(rpos, cur - rpos, 1);
}
rpos = cur;
}
cur++;
}
if (rpos > lpos) {
// 最后一个R且右边没有L
falls[cnt++] = new FallInfo(rpos, n - rpos - 1, 1);
}
for (int i = 0; i < cnt; i++) {
if (falls[i].dir == 0) {
for (int j = falls[i].pos; j >= falls[i].pos - falls[i].len; j--) {
s[j] = 'L';
}
} else {
for (int j = falls[i].pos; j <= falls[i].pos + falls[i].len; j++) {
s[j] = 'R';
}
}
}
return String.valueOf(s);
}
}