2337. 移动片段得到字符串

题目描述:

给你两个字符串 start 和 target ,长度均为 n 。每个字符串 仅 由字符 ‘L’、‘R’ 和 ‘_’ 组成,其中:
字符 ‘L’ 和 ‘R’ 表示片段,其中片段 ‘L’ 只有在其左侧直接存在一个 空位 时才能向 左 移动,而片段 ‘R’ 只有在其右侧直接存在一个 空位 时才能向 右 移动。
字符 ‘__’ 表示可以被 任意 ‘L’ 或 ‘R’ 片段占据的空位。
如果在移动字符串 start 中的片段任意次之后可以得到字符串 target ,返回 true ;否则,返回 false 。

示例:

来源:力扣(LeetCode)
来源:力扣(LeetCode)
来源:力扣(LeetCode)

解题思路:

由于通过字符个数和顺序排除一部分,在通过判断每个“L”字符能不能往前移,每个“R”字符能不能往后移。

相关代码:

class Solution {
    public boolean canChange(String start, String target) {
        if(!start.replace("_","").equals(target.replace("_",""))) {
            return false;
        }
        int[] s=new int[start.replace("_","").length()];
        int[] t=new int[target.replace("_","").length()];
        index(start,s);
        index(target,t);
        for(int i=0;i<s.length;i++) {
            if(start.charAt(s[i])=='L'&&s[i]<t[i]||start.charAt(s[i])=='R'&&s[i]>t[i]) return false;
        }
        return true;
    }
    public void index(String x,int[] n) {
        int j=0;
        for(int i=0;i<x.length();i++) {
            if(x.charAt(i)!='_') {
                n[j]=i;
                j++;
            }
        }
    }
}

代码效率:

来源:力扣(LeetCode)

<think> 我们参考了引用[1]中关于统计字符出现次数的方法,但用户需要的是统计字符串片段(子字符串)出现的次数。 在Java中,我们可以使用String类的indexOf方法,通过循环查找子字符串并计数来实现。 具体步骤: 1. 初始化一个计数器count为0,以及一个索引index初始为0。 2. 使用循环,在每次循环中,使用indexOf(String str, int fromIndex)方法从当前索引开始查找子字符串。 3. 如果找到,则计数器加1,并更新查找起始索引为找到的位置加上子字符串的长度(以避免重叠计数,如果允许重叠则加1)。 4. 如果没找到,则退出循环。 5. 返回计数器的值。 注意:用户的问题是关于字符串片段(可能是多个字符)而不是单个字符。因此,不能像引用[1]中那样逐个字符比较。 另外,引用[2]和[3]提到了正则表达式,但这里我们使用字符串操作即可,正则表达式适用于更复杂的模式匹配。 这里提供两种方法:一种使用循环和indexOf(不重叠计数),另一种使用split方法(简单但不准确,特别是当子字符串在开头或结尾时,或者子字符串为空时会有问题)。 我们推荐使用indexOf方法,因为它更直接且效率较高。 下面是一个使用indexOf方法统计子字符串出现次数的Java方法示例(不重叠): </think> 在Java中,获取字符串片段(子字符串)在字符串中出现次数的方法主要有两种高效实现方式: ### 方法1:使用`indexOf()`循环查找(推荐) ```java public static int countSubstringOccurrences(String str, String substring) { if (substring.isEmpty()) return 0; // 处理空子串 int count = 0; int index = 0; while ((index = str.indexOf(substring, index)) != -1) { count++; index += substring.length(); // 移动搜索位置 } return count; } ``` **使用示例:** ```java String text = "Java is to JavaScript what car is to carpet"; String fragment = "Java"; int occurrences = countSubstringOccurrences(text, fragment); // 返回2 ``` ### 方法2:使用`split()`方法(简单但低效) ```java public static int countWithSplit(String str, String substring) { return str.split(substring, -1).length - 1; } ``` **注意事项:** 1. 两种方法都**区分大小写**,如需忽略大小写: ```java str = str.toLowerCase(); substring = substring.toLowerCase(); // 再调用计数方法 ``` 2. 空子串处理:方法1已处理空字符串,方法2需额外检查 3. 重叠子串:上述方法默认不统计重叠情况(如"aaa"中"aa"只出现2次而非3次) ### 性能对比 | 方法 | 时间复杂度 | 适用场景 | |--------------|------------|-----------------------------| | `indexOf`循环 | $O(n)$ | 通用场景(推荐) | | `split`分割 | $O(n)$ | 短文本简单场景(不推荐大文本)| ### 示例解析 对于字符串`"ababa"`和子串`"aba"`: ```java countSubstringOccurrences("ababa", "aba") // 返回1(非重叠) countWithSplit("ababa", "aba") // 返回1 ``` > 提示:如需统计重叠出现次数(如`"ababa"`中`"aba"`出现2次),修改`indexOf`循环中的位置移动逻辑为`index++`即可[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值