In a string composed of 'L''R', and 'X' characters, like "RXXLRXRXL", a move consists of either replacing one occurrence of "XL" with "LX", or replacing one occurrence of "RX" with "XR". Given the starting string start and the ending string end, return True if and only if there exists a sequence of moves to transform one string to the other.

Example:

Input: start = "RXXLRXRXL", end = "XRLXXRRLX"
Output: True
Explanation:
We can transform start to end following these steps:
RXXLRXRXL ->
XRXLRXRXL ->
XRLXRXRXL ->
XRLXXRRXL ->
XRLXXRRLX

Note:

  1. 1 <= len(start) = len(end) <= 10000.
  2. Both start and end will only consist of characters in {'L', 'R', 'X'}.

这道题给了我们一个只含有L,R,X三个字符的字符串,然后说有两种操作,一种是把 "XL" 变成 "LX",另一种是把 "RX" 变成 "XR"。博主刚开始没有读题意,以为二者是可以互换的,错误的认为认为 "LX" 也能变成 "XL",其实题目这种变换是单向,这种单向关系就是解题的关键,具体来说,就是要把start字符串变成end字符串的话,L只能往前移动,因为是把 "XL" 变成 "LX",同样,R只能往后移动,因为是把 "RX" 变成 "XR"。题目给的那个例子并不能很好的说明问题,博主之前那种双向变换的错误认知会跪在这个例子:

start = "XXRXXLXXXX"
end  = "XXXXRXXLXX"

我们观察这个test case,可以发现start中的R可以往后移动,没有问题,但是start中的L永远无法变到end中L的位置,因为L只能往前移。这道题被归类为brainteaser,估计就是因为要观察出这个规律吧。那么搞明白这个以后,我们其实可以用双指针来解题,思路是,我们每次分别找到start和end中非X的字符,如果二者不相同的话,直接返回false,想想问什么?这是因为不论是L还是R,其只能跟X交换位置,L和R之间是不能改变相对顺序的,所以如果分别将start和end中所有的X去掉后的字符串不相等的话,那么就永远无法让start和end相等了。这个判断完之后,就来验证L只能前移,R只能后移这个限制条件吧,当i指向start中的L时,那么j指向end中的L必须要在前面,所以如果i小于j的话,就不对了,同理,当i指向start中的R,那么j指向end中的R必须在后面,所以i大于j就是错的,最后别忘了i和j同时要自增1,不然死循环了,参见代码如下:

解法一:

class Solution {
public:
bool canTransform(string start, string end) {
int n = start.size(), i = , j = ;
while (i < n && j < n) {
while (i < n && start[i] == 'X') ++i;
while (j < n && end[j] == 'X') ++j;
if (start[i] != end[j]) return false;
if ((start[i] == 'L' && i < j) || (start[i] == 'R' && i > j)) return false;
++i; ++j;
}
return true;
}
};

下面这种解法也挺巧妙的,这里我们使用两个计数器cntL和cntR,分别来统计L和R出现的次数,统计方法时,start中出现了L或R,计数器自增1,end中出现了L或R,计数器自减1。注意我们检测的顺序很重要,由于start中的R必须在end中的R前面,所以我们要先检测start中的R,同理,由于end中的L必须要在start中的L前面,所以我们要先检测end中的L,那么四个if写完后,如果cntL或者cntR中有任何一个小于0了,说明限制条件被打破了,返回false,或者当二者都大于0的时候,说明此时不匹配了,参见上面解法中对于去掉所有的X的解释,一个道理,说明L和R的相对顺序不同了,那么也是false。最终for循环退出后,如果cntL和cntR均为0的时候,才返回true,否则就是false,参见代码如下:

解法二:

class Solution {
public:
bool canTransform(string start, string end) {
int n = start.size(), cntL = , cntR = ;
for (int i = ; i < n; ++i) {
if (start[i] == 'R') ++cntR;
if (end[i] == 'L') ++cntL;
if (start[i] == 'L') --cntL;
if (end[i] == 'R') --cntR;
if (cntL < || cntR < || cntL * cntR != ) return false;
}
return cntL == && cntR == ;
}
};

参考资料:

https://leetcode.com/problems/swap-adjacent-in-lr-string/solution/

https://leetcode.com/problems/swap-adjacent-in-lr-string/discuss/126397/Simple-C++-solution-12ms-O(N)-time-and-O(1)-space

https://leetcode.com/problems/swap-adjacent-in-lr-string/discuss/113789/Simple-Java-one-pass-O(n)-solution-with-explaination

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

[LeetCode] Swap Adjacent in LR String 交换LR字符串中的相邻项的更多相关文章

  1. [LeetCode] Reverse Words in a String III 翻转字符串中的单词之三

    Given a string, you need to reverse the order of characters in each word within a sentence while sti ...

  2. [LeetCode] Reverse Words in a String II 翻转字符串中的单词之二

    Given an input string, reverse the string word by word. A word is defined as a sequence of non-space ...

  3. [LeetCode] 186. Reverse Words in a String II 翻转字符串中的单词 II

    Given an input string, reverse the string word by word. A word is defined as a sequence of non-space ...

  4. [LeetCode] 557. Reverse Words in a String III 翻转字符串中的单词 III

    Given a string, you need to reverse the order of characters in each word within a sentence while sti ...

  5. [LeetCode] Find All Anagrams in a String 找出字符串中所有的变位词

    Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. Strings ...

  6. [LeetCode] 438. Find All Anagrams in a String 找出字符串中所有的变位词

    Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. Strings ...

  7. LeetCode刷题:Reverse Words in a String(翻转字符串中的单词)

    题目 Given an input string, reverse the string word by word. For example, Given s = "the sky is b ...

  8. [Swift通天遁地]五、高级扩展-(14)扩展String快速计算字符串中的各种数学表达式

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  9. [LeetCode] Remove Duplicates from Sorted Array II 有序数组中去除重复项之二

    Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For exampl ...

随机推荐

  1. 【转】Reflector、reflexil、De4Dot、IL相关操作指令合集

    PS:CTRL+F 输入你需要的内容,可以快速查找页面上的内容. 名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. ...

  2. [Tex学习笔记]小于等于一个常数乘以...

    偏微分的论文中常用: 小于等于一个常数乘以... 这个要怎么输入呢. 只要输入\lesssim 就能得到 $\lesssim$...哈哈. 以前知道, 但是忘记了. 现在又要用.

  3. requests中自定义adapter

    # encoding:utf-8 import sslfrom requests import sessionsfrom requests import Requestfrom requests.ad ...

  4. VIM --使用进阶 -- 插件篇 -- YouCompleteMe -- nerdtree

    系统:ubuntu: 资源:https://github.com/ 其他:想了解都要哪些好用的插件,推荐大家读 http://blog.csdn.net/mergerly/article/detail ...

  5. 使用PHP中的ajax做登录页面、验证用户名是否可用、动态调用数据库

    1.ajax的基础知识 ajax是结合了jquery.php等几种技术延伸出来的综合运用的技术,不是新的内容.ajax也是写在<script>标签里面的. 如果使用ajax一定是要有1个处 ...

  6. 剑指Offer编程题2——替换空格

    剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...

  7. day14 集合与函数

    数据类型和变量总结 字符串.数字.列表.元组.字典 可变:列表,字典 不可变:修改变量的值ID变,字符串,数字,元组 访问顺序: 直接访问:数字 顺序访问:字符串,列表,元组 映射:字典 存放元素个数 ...

  8. SlopeOne

    相信大家对如下的Category都很熟悉,很多网站都有类似如下的功能,“商品推荐”,"猜你喜欢“,在实体店中我们有导购来为我们服务,在网络上 我们需要同样的一种替代物,如果简简单单的在数据库 ...

  9. 微信小程序picker组件 - 省市二级联动

    picker 从底部弹起的滚动选择器,现支持五种选择器,通过mode来区分,分别是普通选择器,多列选择器,时间选择器,日期选择器,省市区选择器,默认是普通选择器. picker官方文档链接 由于项目需 ...

  10. 剑指offer字符串1

    面试题5:替换空格 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. class Solu ...