「这是我参与2022首次更文挑战的第34,活动详情查看:2022首次更文挑战」
838. 推多米诺
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' 或 '.'
分析
根据题目我们可以看出米诺骨牌共有三种状态,分别是L、.、R对应这从从右往左推、骨牌直立、左往右推。了解完米诺骨牌的状态后,我们再来了解一下状态会产生那些影响,当我们从右往左推,左测的骨牌也会往左倒比如".L":该字符串修改为"LL",反之左往右推".R":该字符串修改为"RR"。当然左侧从左往右、右侧从右往左推会"R...L":该字符串修改为"RR.LL"。
我们为了方便计算将dominoes默认左侧L,右侧为R。这样我们把推骨牌的情况简化了。
分步实现
将 dominoes 转换成 arr ,变量n赋值数组arr长度,j存在下个骨牌状态的下标。默认数组左右俩侧位let cur = "L"、let pev = "L"。
const arr = [...dominoes];
let n = arr.length
let j = 0
let cur = "L"
let pev = "R"
通过判断目前骨牌状态是否是.,从而找到下一个非.状态的骨牌状态。并将per赋值为arr[j]当然如果超过说明已经是最后一个了就赋值为默认的R。
j = i;
while (j < n && arr[j] == '.') {
j++;
}
pev = j < n ? arr[j] : 'R';
通过不遍历判断cur === pev是否一样,一样则中间所有的.都变为pev。如果cur === 'R' && pev === 'L'则说明是对这推的。
for(let i=0; i<n; ){
j = i;
while (j < n && arr[j] == '.') {
j++;
}
pev = j < n ? arr[j] : 'R';
if (cur === pev) {
while (i < j) {
arr[i++] = pev;
}
} else if (cur === 'R' && pev === 'L') {
let k = j - 1;
while (i < k) {
arr[i++] = 'R';
arr[k--] = 'L';
}
}
cur = pev;
i = j + 1;
代码实现
/**
* @param {string} dominoes
* @return {string}
*/
var pushDominoes = function(dominoes) {
const arr = [...dominoes];
let n = arr.length
let j = 0
let cur = "L"
let pev = "R"
for(let i=0; i<n; ){
j = i;
while (j < n && arr[j] == '.') {
j++;
}
pev = j < n ? arr[j] : 'R';
if (cur === pev) {
while (i < j) {
arr[i++] = pev;
}
} else if (cur === 'R' && pev === 'L') {
let k = j - 1;
while (i < k) {
arr[i++] = 'R';
arr[k--] = 'L';
}
}
cur = pev;
i = j + 1;
}
return arr.join("")
};