代码随想录算法训练营第八天|344.反转字符串 、541. 反转字符串II、剑指Offer 05.替换空格 、151.翻转字符串里的单词、剑指Offer58-II.左旋转字符串

一. 字符串相关算法题

344.反转字符串

思路

  1. 使用左右双指针分别指向字符串数组的头和尾
  2. 交换左右指针的字符,然后左右指针前移right–和left ++,直到两个指针相遇
class Solution {
    public void reverseString(char[] s) {
        //双指针
        int left = 0;
        int right = s.length-1;
        char temp;
        while (left<right){
            temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            right--;
            left ++ ;
        }
    }
}

541.反转字符串Ⅱ

思路

  1. 根据题目可以简化为两种情况,剩余字符长度小于等于2k且大于等于k;剩余字符长度小于k,然后针对这两种情况通过双指针法交换字符
  2. 判断剩余长度小于等于2k大于等于k时可以简化判定条件为:i+k<=String.length,此时的左右指针分别为:i,i+k-1
  3. 除了上面的情况就是长度小于k了:此时左右指针分别为:i,String.length()-1;
  4. 要注意的是可以在for循环中简化循环操作,每次i的跨度为2*k
class Solution {
    public String reverseStr(String s, int k) {
        char[] chars = s.toCharArray();
        int left = 0;
        int rigih = 0;
        for (int i = 0; i < chars.length; i+=2*k) {

            //剩余字符小于2k,大于等于k
            if (i+k<= chars.length){
                reverseSubArray(i,i+k-1,chars);
                continue;
            }

            reverseSubArray(i, chars.length-1,chars);

        }

        return new String(chars);
    }

    private void reverseSubArray(int left, int right, char[] chars){
        char temp;
        while (left<right){
            temp = chars[left];
            chars[left] = chars[right];
            chars[right] = temp;
            left++;
            right--;
        }
    }
}

剑指offer 05.替换空格

通过复制字符串的方式

思路
  1. 创建一个StringBuilder,然后遍历字符串,遇见空格就在后面拼接%20
  • 时间复杂度O(n)
  • 空间复杂度O(n)
class Solution {
    public String replaceSpace(String s) {
        char[] chars = s.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i]==' '){
                sb.append("%20");
            }else {
                sb.append(chars[i]);
            }
        }
        return sb.toString();
    }
}

通过双指针的方式

  1. 首先创建字符串长度为空格数,然后空格数乘以3拼接到原来的字符串中
  2. 然后定义左右双指针分别指向原来字符串末端和新字符串末端
  3. 从后向前遍历左指针遇到非空字符放到右指针,遇到空字符,右指针向前填充%20就这样直至结束
class Solution {
    public String replaceSpace(String s) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i)==' '){
                stringBuilder.append("  ");
            }
        }
        int left = s.length()-1;
        s+=stringBuilder.toString();
        int right = s.length()-1;
        char[] chars = s.toCharArray();
        while (left>=0){
            System.out.println(left +"->"+right+" "+ chars[left]);
            if (chars[left]==' '){
                chars[right--] = '0';
                chars[right--] = '2';
                chars[right] = '%';
            }else {
                chars[right] = chars[left];
            }
            left--;
            right--;
        }
        return new String(chars);
    }

151.反转字符串中的单词

思路

  1. 去除字符串中多余的空格
  2. 反转字符串
  3. 反转字符串中每个单词
class Solution {
    public String reverseWords(String s) {
        //移除多余空格
        StringBuilder stringBuilder = removeSpace(s);
        char[] chars = stringBuilder.toString().toCharArray();
        //反转
        reverse(chars,0, chars.length-1);
        //再反转单词
        int start = 0;
//        for (int i = 0; i < chars.length; i++) {
//            if (chars[i] == ' '){
//                reverse(chars,start,i-1);
//                start = i+1;
//                continue;
//            }
//            //最后一个单词
//            if (i== chars.length-1){
//                reverse(chars,start,i);
//            }
//        }
//        上面反转单词比较麻烦
        int end = 1;
        while (start< chars.length){
            //寻找单词end
            while (end< chars.length && chars[end]!=' ') end++;
            reverse(chars,start,end-1); //这里end-1指向空格的前一位
            start = end+1;
            end = start+1;
        }
        return new String(chars);
    }

    private void reverse(char[] chars,int left, int right){
        char temp ;
        while (left<right){
            temp = chars[left];
            chars[left] = chars[right];
            chars[right] = temp;
            left++;
            right--;
        }

    }

    private StringBuilder removeSpace(String s){
        int left = 0;
        int right = s.length()-1;
        //移除首尾空格
        while (s.charAt(left)==' ') left++;
        while (s.charAt(right)==' ') right--;
        StringBuilder stringBuilder = new StringBuilder();
        while (left<=right){
            if (s.charAt(left)!=' '|| s.charAt(left-1)!=' '){
                stringBuilder.append(s.charAt(left));
            }
            left++;
        }
        return stringBuilder;
    }
}

剑指offer 56-Ⅱ.左旋字符串

字符串拼接

思路
  • 创建一个新字符串以n为分界线先拼接后半段再拼接前半段
class Solution {
    public String reverseLeftWords(String s, int n) {
        //双指针队列
        char[] chars = s.toCharArray();
        int left = 0;
        int right = n;
        StringBuilder stringBuilder = new StringBuilder();
        //拼接后半段
        while (right<chars.length){
            stringBuilder.append(chars[right++]);
        }
        //拼接前半段
        while (left<n){
            stringBuilder.append(chars[left++]);
        }
        return stringBuilder.toString();
    }
}

通过反转实现

思路
  • 整体反转再局部反转
  1. 以n为分界线反转前后子串
  2. 反转整个字符串
class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] chars = s.toCharArray();
        //局部反转
        reverse(chars,0,n-1);
        reverse(chars,n, chars.length-1);
        //整体反转
        reverse(chars,0, chars.length-1);

        return new String(chars);

    }

    public void reverse(char[] chars,int left, int right){
       char temp ;
       while (left<right){
           temp = chars[left];
           chars[left] = chars[right];
           chars[right] = temp;
           left++;
           right--;
       }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值