[LeetCode] Swap Adjacent in LR String 交换LR字符串中的相邻项
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 <= len(start) = len(end) <= 10000
.- 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/
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Swap Adjacent in LR String 交换LR字符串中的相邻项的更多相关文章
- [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 ...
- [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 ...
- [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 ...
- [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 ...
- [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 ...
- [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 ...
- LeetCode刷题:Reverse Words in a String(翻转字符串中的单词)
题目 Given an input string, reverse the string word by word. For example, Given s = "the sky is b ...
- [Swift通天遁地]五、高级扩展-(14)扩展String快速计算字符串中的各种数学表达式
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- [LeetCode] Remove Duplicates from Sorted Array II 有序数组中去除重复项之二
Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For exampl ...
随机推荐
- 第29月第14天 evpp
1.evpp https://github.com/Qihoo360/evpp/tree/master/examples/recipes/self_control_timer https://blog ...
- java.util.zip.ZipException: invalid entry size
启动maven项目时报java.util.zip.ZipException: invalid entry size (expected 7612 but got 5955 bytes) 可能是mave ...
- WebService - 基础概念
一.WebService到底是什么 一言以蔽之:WebService是一种跨编程语言和跨操作系统平台的远程调用技术. 所谓跨编程语言和跨操作平台,就是说服务端程序采用java编写,客户端程序则可以采用 ...
- [Harbor]Harbor简要介绍
前一段时间写过一篇文章:[Kubernetes]CentOS7下搭建Harbor仓库,只是知道了如何搭建,但是对于背后的整体架构还不是太清楚,这篇文章就来讲讲. 默认情况下,Harbor运行起来后有如 ...
- formData 对象 与 Content-Type 类型
FormData FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据.其主要用于发送表单数据,但亦可用于发送带键数据(keyed data),而独立于表单使用.如 ...
- ASP.NET Core之中间件
本文翻译自:http://www.tutorialsteacher.com/core/aspnet-core-middleware 基本概念 ASP.NET Core引入了中间件的概念,中间件是在AS ...
- 浅谈z-index
z-index使用条件 CSS3之前,z-index属性只有和定位元素在(postion不为static的元素)一起的时候才会有作用,但CSS3中flex盒子的子元素也可以设置z-index.理论上来 ...
- VC调用静态库、动态库
静态库 // 相对路径 或者 绝对路径 #include "yourlib.h" //相对路径 或者 绝对路径 #pragma comment(lib, "yourlib ...
- 10分钟理解JS引擎的执行机制
首先,请牢记2点: (1) JS是单线程语言 (2) JS的Event Loop是JS的执行机制.深入了解JS的执行,就等于深入了解JS里的event loop 1.灵魂三问 (1) JS为什么是单线 ...
- Spring Boot+CXF搭建WebService(转)
概述 最近项目用到在Spring boot下搭建WebService服务,对Java语言下的WebService了解甚少,而今抽个时间查阅资料整理下Spring Boot结合CXF打架WebServi ...