力扣 每日一题 777. 在LR字符串中交换相邻字符难度:中等,rating: 1938(思维)

Posted nefu-ljw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣 每日一题 777. 在LR字符串中交换相邻字符难度:中等,rating: 1938(思维)相关的知识,希望对你有一定的参考价值。

题目链接

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

题目来源于:第70场周赛 Q3 rating: 1938

类似题目:https://leetcode.cn/problems/move-pieces-to-obtain-a-string/

思路

题意的浅层描述是:start串的XL能被替换为LX,RX能被替换为XR。

对于start串的替换操作,稍加扩展可以得到:

  1. L能够越过左边的若干个X,但是不能越过L或R。
  2. R能够越过右边的若干个X,但是不能越过L或R。

例如 start=RXXLRXRXL -> RLXXXXRRL。

代码一

开两个vector来存两个子串中L、R的位置和字符,便于进行比较。

struct node
    int pos; // 在字符串中的位置
    char val; // 字符
;

class Solution 
    vector<node> start_LR;
    vector<node> end_LR;

  public:
    bool canTransform(string start, string end) 
    int n=start.size();
    int m=end.size();
    if (n!=m) 
        return 0;
    
    if(n==1)
        // 特判
        return start==end;
    
    for(int i=0;i<n;i++)
        if(start[i]!='X')
            start_LR.push_back(i,start[i]);
        
        if(end[i]!='X')
            end_LR.push_back(i,end[i]);
        
    
    // 首先,start串和end串中的L,R字符总数必须相同
    if(start_LR.size()!=end_LR.size())
        return 0;
    
    for(int i=0;i<start_LR.size();i++)
        node st=start_LR[i];
        node ed=end_LR[i];
        if(st.val!=ed.val)
            return 0;
        
        if((st.val=='L'&&st.pos<ed.pos) || (st.val=='R'&&st.pos>ed.pos))
            // 当start串的L在end串的对应L的左边时,可以移动到end串的L位置;
            // 当start串的R在end串的对应L的右边时,可以移动到end串的R位置;
            return 0;
        
    
    return 1;
    // end function
;   // end class

/*
"XRRXRX"
"RXLRRX"
ans: false

"XXXXXLXXXX"
"LXXXXXXXXX"
ans: true

"RXXLRXRXL"
"XRLXXRRLX"
ans: true

"X"
"L"
ans: true

"RXX"
"RXL"
ans: false

"XXXL"
"LXXR"
ans: false

"RXXLRXRXL"
"XRLXXRRLX"
ans: true
*/

代码二

与代码一相比,这个省一点时间和空间,但是细节比较麻烦。

class Solution 
 public:
  bool canTransform(string start, string end) 
    int n = start.size();
    int m = end.size();
    if (n != m) 
      return 0;
    
    if(n == 1)
        // 特判
        return start==end;
    
    int num1=0,num2=0,num3=0,num4=0;
    for(int i=0;i<n;i++)
        if(start[i]=='L')
            num1++;
        
        if(start[i]=='R')
            num2++;
        
        if(end[i]=='L')
            num3++;
        
        if(end[i]=='R')
            num4++;
        
    
    // 首先,start串和end串中的L,R字符总数必须相同
    if(!(num1==num3&&num2==num4))
        return 0;
    
    int i = 0, j = 0;
    while (i < n) 
      // printf("i=%d j=%d\\n",i,j);
      // 从i位置开始,找到start串为L或R的字符
      while (start[i] == 'X') 
        i++;
      
      if(i==n)
          break;
      
      // 根据start[i]找end中下一个和start[i]相同的
      while (j < m && end[j] != start[i])   // 例如start[i]=R end[j]=X或L
        // R和L不能互相越过对方
        if ((start[i] == 'L' && end[j] == 'R') || (start[i] == 'R' && end[j] == 'L')) 
          return 0;
        
        // 越过X
        j++;
      
      if (j == m)   // 没找到相同的(比如全是X)
        return 0;
      
      assert(start[i] == end[j]);
      if ( (start[i] == 'L' && j > i) || (start[i] == 'R' && i > j) ) 
        return 0;
      
      i++;
      j++;
      // end while(i<n)
    return 1;
    // end function
;   // end class

以上是关于力扣 每日一题 777. 在LR字符串中交换相邻字符难度:中等,rating: 1938(思维)的主要内容,如果未能解决你的问题,请参考以下文章

777. 在LR字符串中交换相邻字符 : 双指针运用题

777.在LR字符串中交换相邻字符

力扣 每日一题 801. 使序列递增的最小交换次数难度:困难,rating: 2066(动态规划)

力扣 每日一题 801. 使序列递增的最小交换次数难度:困难,rating: 2066(动态规划)

冒泡排序与每日一题

力扣每日一题 1221. 分割平衡字符串