力扣 每日一题 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串的替换操作,稍加扩展可以得到:
- L能够越过左边的若干个X,但是不能越过L或R。
- 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(思维)的主要内容,如果未能解决你的问题,请参考以下文章
力扣 每日一题 801. 使序列递增的最小交换次数难度:困难,rating: 2066(动态规划)