推多米诺
难度:
标签:
题目描述
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.."
提示:
n == dominoes.length
1 <= n <= 105
dominoes[i]
为'L'
、'R'
或'.'
代码结果
运行时间: 100 ms, 内存: 17.4 MB
/*
* 思路:
* 使用 Java Stream 来简化处理过程。
* 1. 使用一个字符数组来处理字符串的变化。
* 2. 使用两个数组 left 和 right 来记录每个位置被左侧和右侧推到的时间。
* 3. 使用 IntStream 进行遍历,分别从左到右和从右到左填充 right 和 left 数组。
* 4. 最后一次遍历,通过比较 left 和 right 的值来确定每个位置的最终状态。
*/
import java.util.stream.IntStream;
public class Solution {
public String pushDominoes(String dominoes) {
int n = dominoes.length();
char[] result = dominoes.toCharArray();
int[] left = new int[n];
int[] right = new int[n];
IntStream.range(0, n).forEach(i -> right[i] = n);
IntStream.range(0, n).forEach(i -> {
if (result[i] == 'R') {
for (int j = i; j < n && result[j] != 'L'; j++) {
right[j] = Math.min(right[j], j - i);
}
}
});
IntStream.range(0, n).forEach(i -> left[i] = n);
IntStream.range(0, n).forEach(i -> {
if (result[i] == 'L') {
for (int j = i; j >= 0 && result[j] != 'R'; j--) {
left[j] = Math.min(left[j], i - j);
}
}
});
IntStream.range(0, n).forEach(i -> {
if (left[i] < right[i]) {
result[i] = 'L';
} else if (right[i] < left[i]) {
result[i] = 'R';
} else {
result[i] = '.';
}
});
return new String(result);
}
}
解释
方法:
该题解主要通过模拟多米诺骨牌倒下的过程来解决问题。首先,将输入字符串转换为列表以便修改。接着,使用两个指针i和j来遍历列表,i是当前考虑的起始位置,j用于寻找连续的'.'的结束位置。变量left表示当前段落的左边界状态(即前一个非'.'的字符),right表示当前段落的右边界状态(即第一个非'.'的字符)。根据left和right的不同组合,有以下几种情况:1)如果两边字符相同('L'或'R'),则将中间的'.'全部改为该字符;2)如果左边是'R',右边是'L',则从两边向中间推进,直到两指针相遇或交叉,分别设置为'R'和'L';3)如果左右边界不形成推动力(如'.'或相对的'L'和'R'),则保持中间的'.'不变。在处理完所有段落后,将列表转换回字符串形式作为结果。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
题解中提到如果左右边界相同,会将中间的所有'.'改为该边界字符。这种情况下是否考虑了连续的相同边界字符后跟着'.'的情况?例如'R.....'的处理。
▷🦆
在处理左边界为'R',右边界为'L'的情况时,为何选择将点从两边向中间填充直到指针相遇或交叉?这种方法是否能准确处理所有长度的点段?
▷🦆
题解中未详细说明如何处理边界情况,例如字符串开头和结尾是'.'的情况。在这种情况下,最终状态的'.'如何被确定?
▷