每日力扣-在LR字符串中交换相邻字符

103 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

每日力扣是一个专门用来讲力扣中国每天发布的每日一题的栏目。本专栏不提供题目的解答源码,只讲解思路,目的是养成每日刷题、提高自己手感,从而达到算法熟练的目标。

题目(已做删减处理)

在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。

分析

从题目的内容上分析,这是一道属于字符串的算法题。常见的字符串的算法题,涉及到的知识点有:双指针、KMP等。题目中,我们注意到一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"这个内容,字面上很难理解,但是我们抽象来说,这个条件可以分解成以下两种情况:

  • 如果 L 左侧的字符是X,则将字符 L向左移动一位,将其左侧的 X向右移动一位;
  • 如果 R 右侧的字符是X,则将字符 R向右移动一位,将其左侧的 X向左移动一位。 可以从上面的情况中分析得到,每次的操作,其实只涉及到2个数字。 根据题目中的判定条件,我们可以得到下面的规则:
  • 如果 start[i] 和 end[j]不同,那么意味着当前的字符串不匹配;
  • 如果 start[i] 和 end[j]相同,则当前字符是 L 时应有 i≥j,当前字符是R时应有 i≤j,如果当前字符与两个下标的关系不符合该规则,返回 false。 根据以上的规则,我们可以进行编码了。
  1. 分别赋值i和j,如果i<n,而且i所在的位置为X的话,则认为正常,i++;同理,如果j<n,而且i所在的位置为X的话,则认为正常,j++
int i=0,j=0,n=nums.length();
while(i<n && j<n) {
    if(i<n&&start.charAt(i)=='X') i++;
    if(j<n&&end.charAt(j)=='X') j++;
}

2.如果i和j任意一个都达到结束点,则进行判断是否相等(这个步骤也同样是最后的判断依据,后续不再重复涉及。

if(i===n || j==n) return i==j;
  1. 如果当前的start 和 end 数值不一致,则为错误数据
if (start.charAt(i) != end.charAt(j)) return false;
  1. 如果i<j 的时候,start=L ,则错误;同理,如果i>j 的时候,start=R,则错误
  if (start.charAt(i) == 'L' && i < j) return false;
  if (start.charAt(i) == 'R' && i > j) return false;

总结

相对来说比较困难的一道字符串的题目。最主要的是判断各个情况下的处理步骤。但是面对这种需要进行字符串判断的问题,很容易找到需要涉及到的算法知识点。比如本题就能够很容易的推算出是使用双指针解题。力扣 评估该题目为 mid 题目,相关来说比较客观。对于算法新人,或者是没有熟练掌握字符串和双指针的同学来说,的确可以作为一道深入分析的题目。

结题证明

image.png

image.png