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. Return a string representing the final state.
LeetCode-838: 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 the ith domino has been pushed to the left,
dominoes[i] = 'R', if the ith domino has been pushed to the right, and
dominoes[i] = '.', if the ith domino has not been pushed.
Return a string representing the final state.
This problem is about simulating falling dominoes with specific rules:
Based on the points mentioned above, we can see that for each standing domino, what determines whether it will fall left, right, or stay standing is the distance to the nearest falling domino in either direction.
For each position with a standing domino, what if we calculate:
Then we can compare these distances to determine which force reaches it first. Let us try to explain this with the help of an example: R.....L
First, let us label each position with an index:
Position: 0 1 2 3 4 5 6
Domino: R . . . . . L
For each standing domino (marked with ‘.’), we want to find:
index | nearest R on Left | r-Dist | nearest L on Right | l-Dist | Evaluate Distance | Result |
---|---|---|---|---|---|---|
1 | 0 | 1 | 6 | 5 | 1 < 5 | R R . . . . L |
2 | 0 | 2 | 6 | 4 | 2 < 4 | R R R . . . L |
3 | 0 | 3 | 6 | 3 | 3 == 3 | R R R . . . L |
4 | 0 | 4 | 6 | 2 | 4 > 2 | R R R . L . L |
5 | 0 | 5 | 6 | 1 | 5 > 1 | R R R . L L L |
Then for each ‘.’ position i, we compare $(i - left[i])$ with $(right[i] - i)$ to determine its final state.
Here is a java implementation of the above approach:
public String pushDominoes(String dominoes) {
int n = dominoes.length();
int[] nearestROnLeft = new int[n];
int[] nearestLOnRight = new int[n];
char[] ch = dominoes.toCharArray();
int pos = -1;
// Find nearest 'R' on the left for each position
for(int i=0; i < n; i++){
if(ch[i] == 'R'){
pos = i;
}else if(ch[i] == 'L'){
// If we encounter 'L', we need to reset the position
pos = -1;
}
nearestROnLeft[i] = pos;
}
pos = -1;
// Find nearest 'L' on the right for each position
for(int i=n-1; i >= 0; i--){
if(ch[i] == 'L'){
pos = i;
}else if(ch[i] == 'R'){
// If we encounter 'R', we need to reset the position
pos = -1;
}
nearestLOnRight[i] = pos;
}
// Now we can determine the final state of each domino
for(int i=0; i < n; i++){
// If the domino is standing ('.'), we need to check the distances
if(ch[i] == '.'){
// Calculate distances to nearest 'R' and 'L'
// If there is no 'R' on the left, set distance to max value
// If there is no 'L' on the right, set distance to max value
int rDist = nearestROnLeft[i] == -1 ? Integer.MAX_VALUE : (i-nearestROnLeft[i]);
int lDist = nearestLOnRight[i] == -1 ? Integer.MAX_VALUE : (nearestLOnRight[i] - i);
// Compare distances to determine the final state
// If the distance to 'R' is less than 'L', it will fall right
// If the distance to 'L' is less than 'R', it will fall left
// If they are equal, it will remain standing
if(rDist < lDist){
ch[i] = 'R';
}else if(lDist < rDist){
ch[i] = 'L';
}
}
}
return new String(ch);
}
n
is the length of the input string. We traverse the string a constant number of times.n
is the length of the input string. We use two arrays to store the nearest ‘R’ and ‘L’ positions.Be notified of new posts. Subscribe to the RSS feed.