• 字符串反转


    前言:本文参考代码随想录,加上自己的小总结。
    其中代码随想录的目录安排非常得当,题的难度逐渐递增,这也是我参考的一大依据。
    但是,还是要有自己的思考总结,把他人的转化为自己的,才是真正的掌握。
    这里展示的代码可能不是最优解,但是可以帮助理清其中的区别联系。
    Java宝藏链接
    我不搬运代码,只是记录重点
    在这里插入图片描述
    代码随想录中字符串的目录安排如下:
    在这里插入图片描述
    这里提醒一下:

    String和char[] String s = new String(c); char[] c = s.toCharArray();
    String和StringBuilder String s = sb.toString(); StringBuilder sb =new StringBuilder(s);

    其中1,2,4,5的共同点是都需要反转,那我们就来看这个反转函数。
    反转过程中注意边界值,是开区间还是闭区间。
    以及是否考虑使用StringBuilder.

        /**
         * 用StringBuilder
         * 反转字符串指定区间[start, end]的字符
         */
        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--;
            }
        }
        /**
         * 用char[] c = s.toCharArray();
         * 反转字符串指定区间[start, end]的字符
         */
        public void reverseString(char[] c, int start, int end) {
            while (start < end) {
                char temp = c[start];
                c[start] = c[end];
                c[end] = temp;
                start++;
                end--;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    其中反转字符串Ⅱ是反转字符串Ⅰ的简单变形,变化之处是开始start和end的值
    在这里插入图片描述
    在这里插入图片描述

    class Solution {
        public void reverseString(char[] s) {
            reverse(s,0,s.length-1);
        }
    
        public void reverse(char[] c, int start, int end) {
            while (start < end) {
                char temp = c[start];
                c[start] = c[end];
                c[end] = temp;
                start++;
                end--;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    class Solution {
        public String reverseStr(String s, int k) {
            char[] c = s.toCharArray();
            for(int i = 0; i < c.length; i += 2 * k){
                int start = i;
                //取i+k-1 说明满足如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
                //取c.length - 1 说明满足如果剩余字符少于 k 个,则将剩余字符全部反转。
                int end = Math.min(i+k-1, c.length - 1);
                reverse(c, start, end);
            }
            return new String(c);
        }
    
         public void reverse(char[] c, int start, int end) {
            while (start < end) {
                char temp = c[start];
                c[start] = c[end];
                c[end] = temp;
                start++;
                end--;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述
    反转字符串里的单词和左旋字符串是在反转字符串Ⅰ的基础上,在进行局部反转。
    在这里插入图片描述
    这个题,其中还要我收获到(一)对多余空格的处理(二)单词的切割。

    //先整体反转
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    //对多余空格的处理
    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);
                //sb加入的内容= 非空格内容 + 恰好一个空格
                //恰好一个空格= 前面是非空格(sb.charAt(sb.length() - 1) != ' '&& 自己是空格 && 后面不是空格
                //当是两个以上连续空格是 c == '' && sb.charAt(sb.length() - 1) == ' '不会加入
                if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
                    sb.append(c);
                }
                start++;
            }
            return sb;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    //单词的切割
    private void reverseEachWord(StringBuilder sb) {
            int start = 0;
            int end = 1;
            int n = sb.length();
            while (start < n) {
            	//让end去统计直至遇见空格
                while (end < n && sb.charAt(end) != ' ') {
                    end++;
                }
                reverseString(sb, start, end - 1);
                //start end 的移动讲究end比start大1
                start = end + 1;
                end = start + 1;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    //这个的思路也是先整体反转,需要注意的是在局部反转是注意边界取值
     public String reverseLeftWords(String s, int n) {
            char[] chars = s.toCharArray();
            //整体
            reverse(chars, 0, chars.length - 1);
            //局部
            reverse(chars, 0, chars.length - 1 - n);
            reverse(chars, chars.length - n, chars.length - 1);
            return new String(chars);
        }
    
        public void reverse(char[] chars, int left, int right) {
            while (left < right) {
            //用异或实现交换
                chars[left] ^= chars[right];
                chars[right] ^= chars[left];
                chars[left] ^= chars[right];
                left++;
                right--;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    替换空格,这题破解最快的方式是采用StringBuilder
    在这里插入图片描述

    public static String replaceSpace(String s) {
            if (s == null) {
                return null;
            }
            //选用 StringBuilder 单线程使用,比较快,选不选都行
            StringBuilder sb = new StringBuilder();
            //使用 sb 逐个复制 s ,碰到空格则替换,否则直接复制
            for (int i = 0; i < s.length(); i++) {
                if (s.charAt(i) == ' ') {
                    sb.append("%20");
                } else {
                    sb.append(s.charAt(i));
                }
            }
            return sb.toString();
        }
        
    //方式二:双指针法
    //方式二:双指针法
        public String replaceSpace(String s) {
            if(s == null || s.length() == 0){
                return s;
            }
            //扩充空间,空格数量2倍
            int count = 0;
            for (int i = 0; i < s.length(); i++) {
                if(s.charAt(i) == ' '){
                   count ++;
                }
            }
            //若是没有空格直接返回
            if(count == 0){
                return s;
            }
            //有空格情况 定义一个新数组,两个指针
            char[] newString =new char[s.length() + 2 * count];
            int left = s.length() - 1;//左指针:指向原始字符串最后一个位置
            int right = newString.length-1;//右指针:指向新字符串的最后一个位置
    
            while(left>=0){
                if(s.charAt(left) == ' '){
                    newString[right] = '0';
                    newString[right-1] = '2';
                    newString[right-2] = '%';
                    right -= 3;
                }else{
                    newString[right] = s.charAt(left);
                    right--;
                }
                left--;
            }
            return new String(newString);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    字符串反转介绍到这里,篇幅太长,把字符串匹配放到下一篇。

  • 相关阅读:
    EcoVadis评估资讯-2024年公布的记分卡将受奖牌分数新规则约束
    Vue3中组件数据的传递以及更改
    SWIFT:自我认知微调
    故障诊断 | GADF+Swin-CNN-GAM 的轴承故障诊断模型附matlab代码
    C1. k-LCM (easy version)-Codeforces Round #708 (Div. 2)
    Python 在windows环境下加密文件成.pyd格式
    此芯科技加入绿色计算产业联盟,参编绿色计算产业发展白皮书
    【飞控开发基础教程1】疯壳·开源编队无人机-GPIO(LED 航情灯、信号灯控制)
    知识变现海哥:打造爆款课程的底层逻辑
    【Python开发】一文详解Flask-Login
  • 原文地址:https://blog.csdn.net/qq_44327755/article/details/127753707