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.

Given a string "S" representing the initial state. S[i] = 'L', if the i-th domino has been pushed to the left; S[i] = 'R', if the i-th domino has been pushed to the right; S[i] = '.', if the i-th domino has not been pushed.

Return a string representing the final state.

Example 1:

Input: ".L.R...LR..L.."
Output: "LL.RR.LLRRLL.."

Example 2:

Input: "RR.L"
Output: "RR.L"
Explanation: The first domino expends no additional force on the second domino.

Note:

  1. 0 <= N <= 10^5
  2. String dominoes contains only 'L', 'R' and '.'

这道题给我们摆好了一个多米诺骨牌阵列,但是与一般的玩法不同的是,这里没有从一头开始推,而是在很多不同的位置分别往两个方向推,结果是骨牌各自向不同的方向倒下了,而且有的骨牌由于左右两边受力均等,依然屹立不倒,这样的话骨牌就很难受了,能不能让哥安心的倒下去?!生而为骨牌,总是要倒下去啊,就像漫天飞舞的樱花,秒速五厘米的落下,回到最终归宿泥土里。喂,不要给骨牌强行加戏好么!~ 某个位置的骨牌会不会倒,并且朝哪个方向倒,是由左右两边受到的力的大小决定的,那么可以分为下列四种情况:

1)R....R  ->  RRRRRR

这是当两个向右推的操作连在一起时,那么中间的骨牌毫无悬念的都要向右边倒去。

2)L....L  ->  LLLLLL

同理,

当两个向左推的操作连在一起时,那么中间的骨牌毫无悬念的都要向左边倒去。

3)L....R  ->  L....R

当左边界的骨牌向左推,右边界的骨牌向右推,那么中间的骨牌不会收到力,所以依然保持坚挺。

4)R....L  -> RRRLLL   or   R.....L  ->  RRR.LLL

当左边界的骨牌向右推,右边界的骨牌向左推时,就要看中间的骨牌个数了,若是偶数,那么对半分,若是奇数,那么最中间的骨牌保持站立,其余的对半分。

由于上述四种情况包含了所有的情况,所以我们的目标就是在字符串中找出中间是‘点’的小区间,为了便于我们一次遍历就处理完,我们在dominoes字符串左边加个L,右边加个R,这并不会影响骨牌倒下的情况。我们使用双指针来遍历,其中i初始化为0,j初始化为1,当j指向‘点’时,我们就跳过,目标是i指向小区间的左边界,j指向右边界,然后用 j-i-1 算出中间‘点’的个数,为0表示中间没有点。若此时 i>0,则将左边界加入结果res中。若左右边界相同,那么中间的点都填成左边界,这是上述的情况一和二;若左边界是L,右边界是R,则是上述的情况三,中间还是保持点不变;若左边界是R,右边界是L,则是情况四,那么先加 mid/2 个R,再加 mid%2 个点,最后加 mid/2 个L即可。然后i更新为j,继续循环即可,参见代码如下:

解法一:

class Solution {
public:
string pushDominoes(string dominoes) {
string res = "";
dominoes = "L" + dominoes + "R";
for (int i = , j = ; j < dominoes.size(); ++j) {
if (dominoes[j] == '.') continue;
int mid = j - i - ;
if (i > ) res += dominoes[i];
if (dominoes[i] == dominoes[j]) res += string(mid, dominoes[i]);
else if (dominoes[i] == 'L' && dominoes[j] == 'R') res += string(mid, '.');
else res += string(mid / , 'R') + string(mid % , '.') + string(mid / , 'L');
i = j;
}
return res;
}
};

下面这种解法遍历了两次字符串,第一次遍历是先把R后面的点全变成R,同时累加一个cnt数组,其中cnt[i]表示在dominoes数组中i位置时R连续出现的个数,那么拿题目中的例子1来说,第一次遍历之后,原dominoes数组,修改后的dominoes数组,以及cnt数组分别为:

.L.R...LR..L..
.L.RRRRLRRRL..

我们可以发现cnt数字记录的是R连续出现的个数,第一次遍历只模拟了所有往右推倒的情况,很明显不是最终答案,因为还需要往左推,那么就要把某些点变成L,已经把某些R变成点或者L,这时我们的cnt数组就非常重要,因为它相当于记录了往右推的force的大小。第二次遍历是从右往左,我们找所有L前面的位置,若其为点,则直接变为L。若其为R,那么也有可能变L,此时就要计算往左的force,通过 cnt[i+1] + 1 获得,然后跟往右的force比较,若此位置往右的force大,说明当前骨牌应该往左倒,更新此时cnt[i]为往左的force。若此时左右force相等了,说明当前骨牌不会向任意一遍倒,改为点即可,最终修改后的dominoes数组和cnt数组分别为:

LL.RR.LLRRLL..

解法二:

class Solution {
public:
string pushDominoes(string dominoes) {
int n = dominoes.size();
vector<int> cnt(n);
for (int i = ; i < n; ++i) {
if (dominoes[i - ] == 'R' && dominoes[i] == '.') {
dominoes[i] = 'R';
cnt[i] = cnt[i - ] + ;
}
}
for (int i = n - , cur = ; i >= ; --i) {
if (dominoes[i + ] != 'L') continue;
cur = cnt[i + ] + ;
if (dominoes[i] == '.' || cnt[i] > cur) {
dominoes[i] = 'L';
cnt[i] = cur;
} else if (dominoes[i] == 'R' && cnt[i] == cur) {
dominoes[i] = '.';
}
}
return dominoes;
}
};

类似题目:

Shortest Distance to a Character

参考资料:

https://leetcode.com/problems/push-dominoes/

https://leetcode.com/problems/push-dominoes/discuss/132332/C%2B%2BJavaPython-Two-Pointers

https://leetcode.com/problems/push-dominoes/discuss/132932/C%2B%2B-2-pass-scan-O(2N)-13ms

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Push Dominoes 推多米诺骨牌的更多相关文章

  1. [Swift]LeetCode838. 推多米诺 | Push Dominoes

    There are N dominoes in a line, and we place each domino vertically upright. In the beginning, we si ...

  2. LeetCode.1128-等价多米诺骨牌对的数量(Number of Equivalent Domino Pairs)

    这是小川的第394次更新,第428篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第259题(顺位题号是1128).给定多米诺骨牌列表,当且仅当(a == c且b == d ...

  3. Java实现 LeetCode 838 推多米诺(暴力模拟)

    838. 推多米诺 一行中有 N 张多米诺骨牌,我们将每张多米诺骨牌垂直竖立. 在开始时,我们同时把一些多米诺骨牌向左或向右推. 每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌. 同样地, ...

  4. 【LeetCode】1128. Number of Equivalent Domino Pairs 等价多米诺骨牌对的数量(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典统计 代码 复杂度分析 日期 题目地址:http ...

  5. 省选训练赛第4场D题(多米诺骨牌)

    题目来自FZU2163 多米诺骨牌 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description Vasya很喜欢排多米诺 ...

  6. poj 1717==洛谷P1282 多米诺骨牌

    Dominoes Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6571   Accepted: 2178 Descript ...

  7. 用1 x 2的多米诺骨牌填满M x N矩形的方案数(完美覆盖)

    题意 用 $1 \times 2$ 的多米诺骨牌填满 $M \times N$ 的矩形有多少种方案,$M \leq 5,N < 2^{31}$,输出答案模 $p$. 分析 当 $M=3$时,假设 ...

  8. 【Tsinghua OJ】多米诺骨牌(domino)问题

    (domino.c/cpp)[问题描述] 小牛牛对多米诺骨牌有很大兴趣,然而她的骨牌比较特别,只有黑色和白色的两种.她觉 得如果存在连续三个骨牌是同一种颜色,那么这个骨牌排列便是不美观的.现在她有n个 ...

  9. 【01背包】洛谷P1282多米诺骨牌

    题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...

随机推荐

  1. [Kubernetes]基于角色的权限控制之RBAC

    Kubernetes中有很多种内置的编排对象,此外还可以自定义API资源类型和控制器的编写方式.那么,我能不能自己写一个编排对象呢?答案是肯定的.而这,也正是Kubernetes项目最具吸引力的地方. ...

  2. “Excel-建议不可用于您所选择的数据”错误提示

    Excel作为一项的数据图表绘制软件,在工作中经常用到.“建议不可用于您所选择的数据这一错误提示,我也遇到了几次了,但是每次遇到总是忘了上次是什么原因.这次,写下博客记录.一般都是在复制网页或者其他数 ...

  3. MQTT报文格式

    MQTT报文结构 控制报文由三部分组成: 1.Fixed header 固定报头,所有报文都包含 2.Variable header 可变报头,部分报文包含 3.Body 有效载荷,部分报文包含 固定 ...

  4. Linux小知识收集(不断更新)

    一.说明 以下知识点都来自网络收集,只是给自己记录以免下次同样的问题的时候会忘记,如果知道出处,我都会进行标注,如果侵权的话,请邮件通知我,我会及时删除的 二.知识点 1.将centos的源修改为阿里 ...

  5. vue搭建app, M端项目流程

    思路:安装sass预处理嵌套css,flex布局,flexible手机淘宝适配和fastclick移动300s延迟 打开cmd,使用命令行 1.切换盘符:e: 2.使用vue建立一个项目,具体请看我的 ...

  6. NLP自然语言处理原理及名词介绍

    1. 自然语言概念 自然语言,即我们人类日常所使用的语言,是人类交际的重要方式,也是人类区别其他动物的本质特征. 但是我们只能通过自然语言与人交流,无法与计算机进行交流. 2. 自然语言处理 自然语言 ...

  7. Net Framework 4.7.2 覆盖 Net Framework 4.5 解决办法

    场景:由于c盘空间不够,本机pc又安装了 vs2013 和 vs2017 : 所以通过,github上的一个工具,把vs2013 卸载完毕,只留下vs2017: 导致问题由于项目需要net frame ...

  8. PHP字符过滤方法

    function str_filter_replace($str) { if (empty($str)) return false; $str = htmlspecialchars($str); $s ...

  9. urls控制器

    路由分发include('blog.urls')): 将以指定名称开头的url分发到指定app中去匹配 urlpatterns = [ url(r'^admin/', admin.site.urls) ...

  10. C# 通过 Quartz .NET 实现 schedule job 的处理

    在实际项目的开发过程中,会有这样的功能需求:要求创建一些Job定时触发运行,比如进行一些数据的同步. 那么在 .Net Framework 中如何实现这个Timer Job的功能呢? 这里所讲的是借助 ...