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

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

344.反转字符串

代码

// 第二种方法用temp来交换数值更多人容易理解些
class Solution {
    public void reverseString(char[] s) {
        int l = 0;
        int r = s.length - 1;
        while(l < r){
            char temp = s[l];
            s[l] = s[r];
            s[r] = temp;
            l++;
            r--;
        }
    }
}

题图

344.反转字符串

心得

  • 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解

  • 这一问题,这样基本就想到了双指针的思路

  • image-20221214144428516

  • char [] 和int[] nums一样,都是可以nums.length

    因为是char型数组,里面都是char,所以定义中间变量应该是char						//char temp=s[left];
    
  • 一刷先只留下自己明白的代码

541. 反转字符串II

代码

// 解法3
class Solution {
    public String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        // 1. 每隔 2k 个字符的前 k 个字符进行反转
        for (int i = 0; i< ch.length; i += 2 * k) {
            // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
            if (i + k <= ch.length) {
                reverse(ch, i, i + k -1);
                continue;
            }
            // 3. 剩余字符少于 k 个,则将剩余字符全部反转
            reverse(ch, i, ch.length - 1);
        }
        return  new String(ch);

    }
      // 定义翻转函数
    public void reverse(char[] ch, int i, int j) {
    for (; i < j; i++, j--) {
        char temp  = ch[i];
        ch[i] = ch[j];
        ch[j] = temp;
    }

    }
}

题图

  • image-20221214160156412

心得

  • StringBuffer

  • tostring是全部打印,tochararray是字符串转成字符数组

  • ^=

  • 这是外部for循环都执行完了之后才有的

  • image-20221214161433701

  • 定义的翻转函数和给的函数是平级的

  • image-20221214161623665

  • for第一个可以省略,并且最后一个可以多参数
    for (; i < j; i++, j--)
    
  • 定义的翻转函数,就是刚才练习的那一道翻转字符串的题目

  • public void reverse(char[]ch,int i ,int j){
    //public void reverse(char[],int i ,int j){,应该把形参的类型写出来,也不能忘记名称
    
  • 这里要的是下标,但是i+k不是下标,是距离,所以要-1
    reverse(ch,i,i+k-1)
    
  • return  new String(ch)//什么意思?
    

剑指Offer 05.替换空格

//方式二:双指针法
public String replaceSpace(String s) {
    if(s == null || s.length() == 0){
        return s;
    }
    //扩充空间,空格数量2倍
    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 += str.toString();
    int right = s.length()-1;//右指针:指向扩展字符串的最后一个位置
    char[] chars = s.toCharArray();
    while(left>=0){
         if(chars[left] == ' '){
            chars[right--] = '0';
            chars[right--] = '2';
            chars[right] = '%';
        }else{
            chars[right] = chars[left];
        }
        left--;
        right--;
    }
    return new String(chars);
}

题图

image-20221214164327728

替换空格

image-20221214164639129

心得

  • 同学问了,为什么要从后向前填充,从前向后填充不行么?

    从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素向后移动

  • 其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作

  • 字符串遍历只能用s.charAt(i),根据0-s.length()-1,找到字符串中的字符
    
  • //if(s==null||s.length()==0)
    s和nums[]一样,判空时候与null挂钩
    
  • //s += str.toString();
    原始字符串和扩充的拼接
    
  • image-20221214171250099

  • 拼接之前末尾为left,拼接后末尾为right

  •  str.append("   ")//假如三个空格必须是双引号
    
  • 扩充空间是空格数量的2倍

帖子

151.翻转字符串里的单词(先码上)

indexclass Solution {
   /**
     * 不使用Java内置方法实现
     * <p>
     * 1.去除首尾以及中间多余空格
     * 2.反转整个字符串
     * 3.反转各个单词
     */
    public String reverseWords(String s) {
        // System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]");
        // 1.去除首尾以及中间多余空格
        StringBuilder sb = removeSpace(s);
        // 2.反转整个字符串
        reverseString(sb, 0, sb.length() - 1);
        // 3.反转各个单词
        reverseEachWord(sb);
        return sb.toString();
    }
     private StringBuilder removeSpace(String s) {
        // System.out.println("ReverseWords.removeSpace() called with: s = [" + 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++;
        }
        // System.out.println("ReverseWords.removeSpace returned: sb = [" + sb + "]");
        return sb;
    }
    
     /**
     * 反转字符串指定区间[start, end]的字符
     */
    public void reverseString(StringBuilder sb, int start, int end) {
        // System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]");
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
        }
        // System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]");
    }
    
       private void reverseEachWord(StringBuilder sb) {
        int start = 0;
        int end = 1;
        int n = sb.length();
        while (start < n) {
            while (end < n && sb.charAt(end) != ' ') {
                end++;
            }
            reverseString(sb, start, end - 1);
            start = end + 1;
            end = start + 1;
        }
    }
}

题图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iSJvFjwT-1671016784101)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20221214175817022.png)]

心得

  • 我们将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,单词不就正过来了

  • 都是自己定义的方法
    // 1.去除首尾以及中间多余空格
            StringBuilder sb = removeSpace(s);
            // 2.反转整个字符串
            reverseString(sb, 0, sb.length() - 1);
            // 3.反转各个单词
            reverseEachWord(sb);
            return sb.toString();
    
  • sb.setCharAt(start, sb.charAt(end));是改的操作

  • 字符串要想获取里面的元素,只能调用charAt方法

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

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--;
            }
        }
}

题图

image-20221214184632421

image-20221214184727564

image-20221214184755440

心得

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

344.反转字符串

代码

// 第二种方法用temp来交换数值更多人容易理解些
class Solution {
    public void reverseString(char[] s) {
        int l = 0;
        int r = s.length - 1;
        while(l < r){
            char temp = s[l];
            s[l] = s[r];
            s[r] = temp;
            l++;
            r--;
        }
    }
}

题图

344.反转字符串

心得

  • 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解

  • 这一问题,这样基本就想到了双指针的思路

  • image-20221214144428516

  • char [] 和int[] nums一样,都是可以nums.length

    因为是char型数组,里面都是char,所以定义中间变量应该是char						//char temp=s[left];
    
  • 一刷先只留下自己明白的代码

541. 反转字符串II

代码

// 解法3
class Solution {
    public String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        // 1. 每隔 2k 个字符的前 k 个字符进行反转
        for (int i = 0; i< ch.length; i += 2 * k) {
            // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
            if (i + k <= ch.length) {
                reverse(ch, i, i + k -1);
                continue;
            }
            // 3. 剩余字符少于 k 个,则将剩余字符全部反转
            reverse(ch, i, ch.length - 1);
        }
        return  new String(ch);

    }
      // 定义翻转函数
    public void reverse(char[] ch, int i, int j) {
    for (; i < j; i++, j--) {
        char temp  = ch[i];
        ch[i] = ch[j];
        ch[j] = temp;
    }

    }
}

题图

  • image-20221214160156412

心得

  • StringBuffer

  • tostring是全部打印,tochararray是字符串转成字符数组

  • ^=

  • 这是外部for循环都执行完了之后才有的

  • image-20221214161433701

  • 定义的翻转函数和给的函数是平级的

  • image-20221214161623665

  • for第一个可以省略,并且最后一个可以多参数
    for (; i < j; i++, j--)
    
  • 定义的翻转函数,就是刚才练习的那一道翻转字符串的题目

  • public void reverse(char[]ch,int i ,int j){
    //public void reverse(char[],int i ,int j){,应该把形参的类型写出来,也不能忘记名称
    
  • 这里要的是下标,但是i+k不是下标,是距离,所以要-1
    reverse(ch,i,i+k-1)
    
  • return  new String(ch)//什么意思?
    

剑指Offer 05.替换空格

//方式二:双指针法
public String replaceSpace(String s) {
    if(s == null || s.length() == 0){
        return s;
    }
    //扩充空间,空格数量2倍
    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 += str.toString();
    int right = s.length()-1;//右指针:指向扩展字符串的最后一个位置
    char[] chars = s.toCharArray();
    while(left>=0){
         if(chars[left] == ' '){
            chars[right--] = '0';
            chars[right--] = '2';
            chars[right] = '%';
        }else{
            chars[right] = chars[left];
        }
        left--;
        right--;
    }
    return new String(chars);
}

题图

image-20221214164327728

替换空格

image-20221214164639129

心得

  • 同学问了,为什么要从后向前填充,从前向后填充不行么?

    从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素向后移动

  • 其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作

  • 字符串遍历只能用s.charAt(i),根据0-s.length()-1,找到字符串中的字符
    
  • //if(s==null||s.length()==0)
    s和nums[]一样,判空时候与null挂钩
    
  • //s += str.toString();
    原始字符串和扩充的拼接
    
  • image-20221214171250099

  • 拼接之前末尾为left,拼接后末尾为right

  •  str.append("   ")//假如三个空格必须是双引号
    
  • 扩充空间是空格数量的2倍

帖子

151.翻转字符串里的单词(先码上)

indexclass Solution {
   /**
     * 不使用Java内置方法实现
     * <p>
     * 1.去除首尾以及中间多余空格
     * 2.反转整个字符串
     * 3.反转各个单词
     */
    public String reverseWords(String s) {
        // System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]");
        // 1.去除首尾以及中间多余空格
        StringBuilder sb = removeSpace(s);
        // 2.反转整个字符串
        reverseString(sb, 0, sb.length() - 1);
        // 3.反转各个单词
        reverseEachWord(sb);
        return sb.toString();
    }
     private StringBuilder removeSpace(String s) {
        // System.out.println("ReverseWords.removeSpace() called with: s = [" + 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++;
        }
        // System.out.println("ReverseWords.removeSpace returned: sb = [" + sb + "]");
        return sb;
    }
    
     /**
     * 反转字符串指定区间[start, end]的字符
     */
    public void reverseString(StringBuilder sb, int start, int end) {
        // System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]");
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
        }
        // System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]");
    }
    
       private void reverseEachWord(StringBuilder sb) {
        int start = 0;
        int end = 1;
        int n = sb.length();
        while (start < n) {
            while (end < n && sb.charAt(end) != ' ') {
                end++;
            }
            reverseString(sb, start, end - 1);
            start = end + 1;
            end = start + 1;
        }
    }
}

题图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x127WHJs-1671016784193)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20221214175817022.png)]

心得

  • 我们将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,单词不就正过来了

  • 都是自己定义的方法
    // 1.去除首尾以及中间多余空格
            StringBuilder sb = removeSpace(s);
            // 2.反转整个字符串
            reverseString(sb, 0, sb.length() - 1);
            // 3.反转各个单词
            reverseEachWord(sb);
            return sb.toString();
    
  • sb.setCharAt(start, sb.charAt(end));是改的操作

  • 字符串要想获取里面的元素,只能调用charAt方法

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

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--;
            }
        }
}

题图

image-20221214184632421

image-20221214184727564

image-20221214184755440

心得

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值