777. 在LR字符串中交换相邻字符【双指针】

思路

需要理解start中可以进行的操作:

  1. L只能向左移动,且左侧为X时才能移动;
  2. R只能向右移动,且右侧为X时才能移动;
  3. RL是不能够交换变成LR的。

因此可以通过判断startend中具有相同序号的非X字符:start[i]以及end[j]

这里的序号指:原字符串中非X的字符第几次出现。

  1. 如果start[i] != end[j],直接返回false即可。因为从上面讨论可以知道LR是不能交换顺序的,因此相同序号处的非X字符如果不同则一定无法通过交换获得。
  2. 如果start[i] == end[j] == 'L' && i < j,已知L只能向左移动,而此时i<j,需要向右移动才能交换得到end,因此需要返回false
  3. 如果start[i] == end[j] == 'R' && i > j,已知R只能向由移动,而此时i>j,需要向左移动才能交换得到end,因此需要返回false
  4. 显然如果startendLR的字符数量要相同,否则肯定无法通过交换得到end

实现代码如下:

public class Solution {
    public boolean canTransform(String start, String end) {
        int n = start.length();
        char[] startArray = start.toCharArray();
        char[] endArray = end.toCharArray();

        //start中,R只能往右移动,L只能向左移动
        int i=0,j=0;
        while (i<n || j<n){
            //跳过X
            while(i<n && startArray[i] == 'X') {
                i++;
            }
            while(j<n && endArray[j] == 'X') {
                j++;
            }

            if (i == n || j == n){
                return i==j;  //两个字符串中L+R出现的次数不同,则一定是返回false
            }
            if (startArray[i] != endArray[j]){
                return false;  //L和R是不能够交换的因此L\R顺序不同则返回false;
            }
            if (startArray[i] == 'L' && i<j){
                return false;
            }
            if (startArray[i] == 'R' && i>j){
                return false;
            }

            i++;
            j++;
        }
        return true;
    }
}

在 ARM 汇编,可以使用以下过程将一个字符串插入到另一个字符串: ``` insert_string: push {r4, lr} ; 保存寄存器和返回地址 mov r2, #0 ; 初始化字符串长度为 0 loop: ldrb r3, [r1], #1 ; 读取源字符串的一个字符 cmp r3, #0 ; 检查字符是否为字符串结束符 beq done ; 如果是,跳转到结束 strb r3, [r0], #1 ; 将字符插入到目标字符串 add r2, r2, #1 ; 增加字符串长度 b loop ; 继续循环 done: mov r4, r2 ; 保存字符串长度,用于后面的计算 mov r2, #0 ; 重新将字符串长度初始化为 0 ldrb r3, [r5], #1 ; 读取要插入的字符串的一个字符 cmp r3, #0 ; 检查字符是否为字符串结束符 beq copy ; 如果是,跳转到复制 loop2: strb r3, [r0], #1 ; 将要插入的字符插入到目标字符串 add r2, r2, #1 ; 增加字符串长度 ldrb r3, [r5], #1 ; 读取要插入的字符串的下一个字符 cmp r3, #0 ; 检查字符是否为字符串结束符 bne loop2 ; 如果不是,继续循环 copy: sub r0, r0, r4 ; 将目标字符串指针移到要插入的字符串的末尾 ldr r3, =0xFFFFFFFF ; 将 r3 的值设置为 -1 str r3, [r0], #4 ; 将目标字符串末尾的位置设置为 -1 sub r0, r0, r2 ; 将目标字符串指针移到插入字符串的位置 add r5, r5, r2 ; 将要插入字符串的指针移到末尾 loop3: ldr r3, [r0, #4] ; 读取目标字符串当前位置的值 str r3, [r0, r2, #4] ; 将目标字符串当前位置的值复制到插入字符串的位置 add r2, r2, #4 ; 增加插入字符串的位置 cmp r3, #0xFFFFFFFF ; 检查是否到达目标字符串的末尾 bne loop3 ; 如果没有,继续循环 pop {r4, pc} ; 恢复寄存器和返回 ``` 这个过程的输入参数为: - `r0`:指向目标字符串的指针 - `r1`:指向源字符串的指针 - `r2`:字符串长度计数器(这个参数会在过程被修改) - `r3`:字符读取器 - `r4`:保存字符串长度的寄存器 - `r5`:指向要插入的字符串的指针 这个过程的输出是将要插入的字符串插入到目标字符串的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值