📖本篇内容:leetcode每日一题 838. 推多米诺 脑筋急转弯 或者 正解 双指针~这题很考察模拟逻辑,是一道不错的模拟题
📑 文章专栏:leetcode每日一题《打卡日常》
📆 最近更新:2022年2月17日 leetcode每日一题 688. 骑士在棋盘上的概率 记忆化深搜 简单的板子搜索题
🙊个人简介:一只二本院校在读的大三程序猿,本着注重基础,打卡算法,分享技术作为个人的经验总结性的博文博主,虽然可能有时会犯懒,但是还是会坚持下去的,如果你很喜欢博文的话,建议看下面一行~(疯狂暗示QwQ)
🌇 点赞 👍 收藏 ⭐留言 📝 一键三连 关爱程序猿,从你我做起
🙊写在前面🙊
小付来了哦~小付手机坏了,所以最近更新会延缓一点点,但是做题还是没有忘得qwq,直接网吧一做,人家游戏我刷题,好家伙直接一个另类奇葩来了!
题目
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 <= 10^5
dominoes[i] 为 'L'、'R' 或 '.'
📝思路📝
本题考查知识点
- 小付第一次想的方法是
暴力模拟
,针对于第一次出现的左倾或者右倾 和 第二次出现左倾或者右倾的情况 二者来进行模拟,由题可知: - 当二者出现
LL
情况时,则期间所有的竖直多米诺骨牌,最终都会向左倾,全部为L - 当二者出现
LR
情况时,其中间的多米诺骨牌会维持竖直的原状
。 - 当二者出现
RR
情况时,则期间所有的竖直多米诺骨牌,最终都会向右倾,全部为R - 当二者出现
RL
情况时,则需要对中间的竖直多米诺骨牌进行计数,可能出现奇数个,也可能出现偶数个:1、当出现奇数个
多米诺骨牌时,咱们两两配对
只有最中间的那个多米诺骨牌
既不会左倾
也不会右倾
,而它左侧的骨牌则会右倾全为R
,而它右侧的骨牌则都会左倾全为L
。
注意: 咱们解题的时候可以在其左右两侧分别添加一个左倾多米诺骨牌和一个右倾多米诺骨牌,这样便于双指针求解。
这里参考了 可爱抱抱呀
的题解评论 -----> 一个非常非常努力且厉害的大佬~
⭐代码实现⭐
class Solution {
public String pushDominoes(String dominoes) {
// 先将多米诺骨牌的最左侧添加一个左倾多米诺骨牌、再在最右侧添加一个右倾多米诺骨牌便于题解双指针
dominoes = new StringBuilder("L").append(dominoes).append("R").toString();
// 用于记录结果的
StringBuilder res = new StringBuilder();
// 初始化左侧指针所指位置
int leftCur = 0;
// 初始化右侧指针所指位置
int rightCur = 1;
// 如果当前还没有遍历到最后一块多米诺骨牌时则继续模拟
while (rightCur < dominoes.length()){
// 当模拟期间遇到竖直的多米诺骨牌则将右指针后移
while(rightCur < dominoes.length() && dominoes.charAt(rightCur) == '.')rightCur++;
// 移动完毕之后,获取当前本组的指针字符leftChar 代表左指针字符骨牌
char leftChar = dominoes.charAt(leftCur);
char rightChar = dominoes.charAt(rightCur);
// 1、如果此时两个字符相等 就直接添加相同字符 LL 或者 RR 的情况下 那么他们中间的所有竖直骨牌都会向一侧倾斜
if (leftChar == rightChar){
// 到达右指针之前个字符个数
for (int i = leftCur + 1 ;i < rightCur ;i++){
res.append(leftChar);
}
// 这是第二种情况的考虑了 我们可以先跳过这里 因为我们初始化left指针为L
}else if (leftChar == 'R'){
// 这里cnt计算两者之间有多少个 . 为什么要-1 你画个图根据下标求个数就知道了
int cnt = rightCur - leftCur - 1;
for (int i = 0;i< cnt / 2 ;i++){
res.append('R');
}
// 如果当前是奇数个的话我们还需要为其添加一个中间的竖直骨牌 既不左倾也不右倾
if (cnt % 2 == 1)res.append('.');
for (int i = 0 ;i< cnt / 2;i++){
res.append('L');
}
}else { // 这是第三种情况就是LR情况中间全是竖直的骨牌
for (int i = leftCur + 1;i<rightCur;i++){
res.append('.');
}
}
// 2、将右指针所处的结果进行添加
res.append(rightChar);
// 左侧指针指向右侧指针
leftCur = rightCur;
// 右侧指针 后移
rightCur++;
}
// 返回结果的时候注意 我们一开始在最右侧添加了一个虚拟的右倾骨牌 需要去掉哦~
return res.substring(0,res.length()-1).toString();
}
}
运行结果
🙊写在最后🙊
2022-2-21今天小付打卡了哦~
美好的日出 美好的山河
都因有你存在 而璀璨 耀眼