代码随想录|字符串|leetcode 334,541,115 剑指offer05,58-II

反转字符串

class Solution {
    public void reverseString(char[] s) {
        int left = 0;
        int right = s.length - 1;
        while(left < right){
            char tmp = s[left];
            s[left] = s[right];
            s[right] = tmp;
            left++;
            right--;


        }


    }
}

思路:

  1. 定义双指针

    • left 指针从字符数组的开头开始。
    • right 指针从字符数组的末尾开始。
  2. 反转字符

    • left 小于 right 时,将 s[left]s[right] 的字符交换。
    • 交换后,left 指针向右移动,right 指针向左移动。
  3. 循环直至指针相遇

    • 这样确保了数组的左半部分和右半部分都得到了反转。
class Solution {
    public String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        //每隔2k个字符的前k个字符翻转
        for(int i = 0; i < ch.length; i += 2*k){
            if(i+k <= ch.length){
                reverse(ch, i, i+k-1);
                continue;
            }else{
                //剩余字符少于 k 个,则将剩余字符全部反转
                reverse(ch, i, ch.length-1);
            }
            

        }

        return String.valueOf(ch); //转换为str输出
    }

    public void reverse(char[] ch, int i, int j){
        while(i<j){
            char temp = ch[i];
            ch[i] = ch[j];
            ch[j] = temp;
            i++;
            j--;
        }
    }
}

 思路:

  1. 将字符串转为字符数组: 使用 s.toCharArray() 将字符串转换为字符数组,方便后续的操作。

  2. 分段处理

    • 从索引 0 开始,每隔 2k 个字符,就对这 2k 个字符的前 k 个字符进行反转。这个操作使用了一个循环,循环变量 i 每次增加 2k。
    • 对于每个段,如果当前索引 i 加上 k 小于等于字符数组的长度,那么就将索引从 ii+k-1 的字符反转。
    • 如果当前索引 i 加上 k 大于字符数组的长度,那说明已经处理到了字符数组的末尾,并且剩余的字符不足 k 个,此时将索引从 i 到字符数组末尾的所有字符进行反转。
  3. 字符反转

    • 使用一个辅助函数 reverse 对字符数组中的一段进行反转。reverse 函数使用了双指针技术,一个指针从段的开头开始,另一个指针从段的末尾开始,将这两个指针指向的字符交换,然后两个指针分别向中间移动,直到两个指针相遇。
  4. 返回结果: 使用 String.valueOf(ch) 将字符数组转换回字符串,并作为结果返回。

替换空格

class Solution {
    public String replaceSpace(String s) {
        if(s == null || s.length() == 0){
            return s;
        }

        StringBuilder str = new StringBuilder(); //建立扩展字符串
        for(int i = 0; i < s.length(); i++){
            if(s.charAt(i) == ' '){//表示单个字符用单引号
                str.append("  ");
            }
        }
        //若是没有空格,直接返回字符串
        if(str.length() == 0){
            return s;
        }

        //有空格的情况 定义两个指针
        int left = s.length() - 1; //左指针:指向原始字符串最后一个位置
        s = s + str.toString();
        int right = s.length() - 1; //右指针:指向扩展字符串最后一个位置
        char[] ch = s.toCharArray();
        while(left >= 0){
            if(ch[left] == ' '){
                ch[right--] = '0';
                ch[right--] = '2';
                ch[right] = '%';
            }else{
                ch[right] = ch[left];
            }
            left--;
            right--;
        }

        return new String(ch);


    }
}

思路:

  1. 检查字符串是否为空: 如果输入的字符串s为空或长度为0,则直接返回输入的字符串。

  2. 初始化 StringBuilder: 使用StringBuilder来计算新字符串中需要增加的空间。

  3. 遍历原字符串: 对输入的字符串s进行遍历,每当找到一个空格时,在StringBuilder中追加两个空格。这是因为原字符串中的空格只占一个字符,而"%20"有三个字符,所以需要在原有的基础上增加两个位置。

  4. 检查是否有空格: 如果StringBuilder的长度为0,说明原字符串中没有空格,因此直接返回原字符串。

  5. 替换空格: 在原字符串后面追加StringBuilder中的内容,然后定义两个指针,左指针指向原字符串的最后一个字符,右指针指向新字符串的最后一个字符。

    接下来,进行以下操作:

    • 如果左指针指向的字符是空格,则将右指针指向的位置依次设置为"0"、"2"和"%"。
    • 如果左指针指向的字符不是空格,则将右指针指向的位置设置为左指针指向的字符。

    每次操作后,左右指针都往左移动一个位置。

  6. 返回新字符串: 最后,使用新的字符数组创建一个新的字符串并返回。

反转字符串里的单词

class Solution {
    public String reverseWords(String s) {
        //1.去除首尾以及中间多余空格
        StringBuilder sb = removeSpace(s);
        //2.反转整个字符串
        reverseString(sb, 0, sb.length() - 1);
        //3.反转各个单词
        reverseEachWord(sb);
        return sb.toString();

    }

    private StringBuilder removeSpace(String s){
        int start = 0;
        int end = s.length() - 1;
        while(s.charAt(start) == ' ') start++;
        while (s.charAt(end) == ' ') end--;
        StringBuilder sb = new StringBuilder();
        while (start <= end){
            char c = s.charAt(start);
            if(c != ' ' || sb.charAt(sb.length()-1)!=' '){
                sb.append(c);
            }
            start++;
        }
        return sb;

    }

    public void reverseString(StringBuilder sb, int start, int end){
        while(start < end){
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
        }

    }

    private void reverseEachWord(StringBuilder sb){
        int start = 0; //设置起始指针为0,表示从字符串的开始位置开始
        int end = 1; //设置结束指针为1,用于找到每个单词的结束位置
        int n = sb.length(); //获取字符串的长度
        while(start < n){ //当起始指针仍在字符串长度内时,继续执行循环
            while(end < n && sb.charAt(end) != ' '){ //当结束指针在字符串长度内并且指向的字符不是空格时,移动结束指针
                end++; //它会检查 end 指针所指向的字符是否不是空格,如果不是空格,说明当前字符仍属于当前单词,因此 end 指针会向前移动
            }
            reverseString(sb, start, end - 1);//反转从起始指针到结束指针之间的字符,即反转当前单词
            start = end + 1; //将起始指针移动到下一个单词的开始位置
            end = start + 1; //将结束指针设置为起始指针的下一个位置,准备开始下一个单词的查找
        }
    }

}

 思路:

  1. 去除多余空格: 使用removeSpace函数移除字符串s的前后以及中间连续的空格。这个函数通过两个指针(start 和 end)定位到第一个和最后一个非空格字符。然后,它从头到尾遍历字符串,并只在以下情况下将字符添加到StringBuilder中:

    • 当前字符不是空格;
    • 或者StringBuilder的最后一个字符不是空格。
  2. 反转整个字符串: 使用reverseString函数反转整个字符串。这个函数通过两个指针(start 和 end),从两端向中间移动,交换两端的字符。

  3. 反转每个单词: 使用reverseEachWord函数反转每个单词。这个函数首先设置两个指针(start 和 end)。开始和结束指针的目的是找到每个单词的开始和结束位置。每次找到一个单词后,使用reverseString函数将这个单词反转。

左旋转字符串 

 

class Solution {
    public String reverseLeftWords(String s, int n) {
        int len=s.length();
        StringBuilder sb=new StringBuilder(s);
        reverseString(sb,0,n-1);//注意左闭右闭区间
        reverseString(sb,n,len-1);//
        return sb.reverse().toString();
    }
     public void reverseString(StringBuilder sb, int start, int end) {
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
            }
        }
}

 

思路:

  1. 反转区间为前n的子串
  2. 反转区间为n到末尾的子串
  3. 反转整个字符串

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值