训练营0928|字符串系列(反转I|反转II|替换空格|翻转单词|左旋转字符串)

本文介绍多种字符串操作方法,包括原地反转、部分反转、空格替换、单词顺序反转及字符串旋转等,通过具体示例和代码实现,展示了如何高效处理字符串问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

目录

 344.反转字符串

541.反转字符串II

剑指Offer 05.替换空格

151.反转字符串中的单词

 剑指offer58-II.左旋转字符串


 344.反转字符串

 原地的话采用双指针,互相交换

class Solution {
    /**
     * 翻转字符串--->原地修改数组
     *
     * @param s
     */
    public void reverseString(char[] s) {
        //双指针
        int len = s.length;
        int left = 0, right = len - 1;//left<len/2,right>len/2
        for (left = 0; left < len / 2; left++) {
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            right--;
        }
    }
}

541.反转字符串II

 重点是,start到哪儿了,而且要翻哪个区域。用一个比较长字符串的模拟一下

class Solution {
    /**
     * 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
     * 如果剩余字符少于 k 个,则将剩余字符全部反转。
     * 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
     *
     * @param s
     * @param k
     * @return
     */
    public String reverseStr(String s, int k) {
        char[] chars = s.toCharArray();
        int len = chars.length;
        int start = 0;
        while (len > 0) {
            if (len < k) {
                reversePartStr(chars, start, chars.length - 1);
                break;
            } else if ((len >= k) && (len < 2 * k)) {
                //翻转前k个字符
                reversePartStr(chars, start, start + k - 1);
                break;
            } else {
                reversePartStr(chars, start, start + k - 1);//翻转前k个字符
                len -= 2 * k;
                start += 2 * k;
            }
        }
        return String.valueOf(chars);
    }

    public void reversePartStr(char[] chars, int start, int end) {//翻转索引start到end部分
        if (start > end) {
            return;
        }
        int temp = (end - start + 1) / 2;
        for (int i = start; i < start + temp; i++) {
            char mob = chars[i];
            chars[i] = chars[end];
            chars[end] = mob;
            end--;
        }
    }
}

剑指Offer 05.替换空格

 其实本来第一反应是转成char数组去做,但是空格要转成“%20”并不是一个字符,之后想到是否可以用buffer的replace直接做。

class Solution {
    /**
     * 把s里面的空格替换成%20
     *
     * @param s
     * @return
     */
    public String replaceSpace(String s) {
        StringBuffer buffer = new StringBuffer(s);
        for (int i = 0; i < buffer.length(); i++) {
            if (' ' == buffer.charAt(i)) {
                buffer.replace(i, i + 1, "%20");
            }
        }
        return buffer.toString();
    }
}

然后看了别人的思路之后发现利用char数组的话可以先扩容,然后利用双指针,一个指向扩容之后的结尾,一个指向本来的结尾,进行数据填充。


151.反转字符串中的单词

 更多的利用了库函数去掉首尾的空格,并且利用正则匹配多个空格去分割

然后字符串数组里面进行交换,最后拼成结果。

class Solution {
    /**
     * 反转字符串中单词的顺序
     * 输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。
     * 返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
     *
     * @param s
     * @return
     */
    public String reverseWords(String s) {
        StringBuffer ans = new StringBuffer();
        s = s.trim();
        s = s.replace("\\s+", " ");
        String[] strs = s.split("\\s+");
        int left = 0, right = strs.length - 1;
        for (left = 0; left < strs.length / 2; left++) {
            String temp = strs[left];
            strs[left] = strs[right];
            strs[right] = temp;
            right--;
        }
        for (int i = 0; i < strs.length - 1; i++) {
            ans.append(strs[i]);
            ans.append(" ");
        }
        ans.append(strs[strs.length - 1]);
        return ans.toString();
    }
}

看了解析之后如果空间复杂度为O(1)的话,可以使用快慢指针,即移除空格,慢指针维护边界,快指针去找符合的字符,然后每多个空格添加单个空格。


剑指offer58-II.左旋转字符串

 第一反应还是用StringBuffer,开一个长度为k的新字符串,然后拼在原字符串后面。

但是如果空间复杂度为O(1)的话不使用额外空间只在原字符串上面操作----->使用整体翻转然后局部翻转的策略

* 左旋字符串---->
* 1.翻转前n个字符串
* 2.翻转剩下的字符串
* 3.翻转整个字符串
class Solution {
    /**
     * 左旋字符串---->
     * 1.翻转前n个字符串
     * 2.翻转剩下的字符串
     * 3.翻转整个字符串
     *
     * @param s
     * @param n
     * @return
     */
    public String reverseLeftWords(String s, int n) {
        char[] chars = s.toCharArray();
        ReverseChar(chars, 0, n - 1);
        ReverseChar(chars, n, s.length() - 1);
        ReverseChar(chars, 0, s.length() - 1);
        return new String(chars);
    }

    public void ReverseChar(char[] chars, int start, int end) {//从start到end部分进行反转
        //双指针
        if (start >= end) {
            return;
        }
        int mid = (start + end + 1) / 2;
        while (start < mid) {
            char temp = chars[start];
            chars[start] = chars[end];
            chars[end] = temp;
            start++;
            end--;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值