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

LeetCode 344 反转字符串
题目链接:反转字符串

思路:双指针遍历数组。

package str;

/**
 * @author rpstart
 * @create 2023-07-05 23:12
 */
public class reverseString344 {
    public static void main(String[] args) {
        String str = "hello";
        char[] s = new char[str.length()];
        for (int i = 0; i < str.length(); i++) {
            s[i] = str.charAt(i);
        }
        reverseString(s);
        System.out.println(s);
    }

    public static void reverseString(char[] s) {
        int left = 0;
        int right = s.length - 1;

        while (right > left) {
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
}

LeetCode 541 反转字符串2
题目链接:反转字符串2

思路:在第一个的基础上加了一个遍历顺序。

package str;

/**
 * @author rpstart
 * @create 2023-07-05 23:31
 */
public class reverseStr541 {
    public static void main(String[] args) {
        String s = "abcdefg";
        int k = 2;
        String res = reverseStr(s, k);
        System.out.println(res);
    }

    public static String reverseStr(String s, int k) {
        char[] str = s.toCharArray();
        for (int i = 0; i < str.length; i += 2 * k) {
            int start = i;
            int end = Math.min(str.length - 1, start + k - 1);
            while (end > start) {
                char temp = str[start];
                str[start] = str[end];
                str[end] = temp;
                end--;
                start++;
            }
        }
        return new String(str);
    }


}

LeetCode 剑指offer 05. 替换空格
剑指offer 05. 替换空格

思路:替换空格的思路很简单,由于StringBuilder是可变字符串,可以实现字符串的拼接,因此可以直接将原字符串转化为数组,进行遍历,然后通过使用字符串拼接的形式,形成新的字符串。

package str;

/**
 * @author rpstart
 * @create 2023-07-08 9:27
 */
public class replaceSpace05 {
    public static void main(String[] args) {
        String str = "We are happy";
        String res = replaceSpace(str);
        System.out.println(res);
    }

    public static String replaceSpace(String s) {
        char[] chars = s.toCharArray();
        StringBuilder strb = new StringBuilder();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == ' ') {
                strb.append("%20");
            } else {
                strb.append(chars[i]);
            }

        }
        return strb.toString();
    }
}

这道题如果使用数组来进行处理会减少空间占用,下面用双指针的思路来对该题进行一个实现。
有两个需要注意的点,一是在开始的条件,剪枝处理时,return的是原字符串,而不是null,因为有“”这种情况,里面是空字符串。
二是在while循环中的约束条件,约束条件中的等号是必须要有的,原因是最后遍历到0的时候,不一定原数组不需要变化,默认原来的内容就行,因为有可能是空格,需要继续填充。

 private static String replaceSpace(String s) {
        if (s == null || s.length() == 0) {
            return s;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ' ') {
                //添加两个空格,因为原数组本身有一个空格,最终添加完成之后就是三个空格。
                sb.append("  ");
            }
        }
        if (sb.length() == 0) {
            return s;
        }

        int left = s.length() - 1;
        s += sb.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);
    }

LeetCode 151 反转字符串里的单词
反转字符串里的单词

思路:通过看题目,最直接的思路是先处理字符串的空格问题:对整体字符串去掉开头和结尾的空格,删掉每个单词中多余的空格。
然后对全部字符串进行反转,然后分别对整体字符串中的每个单词进行反转。

package str;

import java.beans.EventHandler;

/**
 * @author rpstart
 * @create 2023-07-08 10:08
 */
public class reverseWords151 {
    public static void main(String[] args) {
        String s = "  hello   world   ";
        String res = reverseWords(s);
        System.out.println(res);
    }

    public static String reverseWords(String s) {
        StringBuilder sb = new StringBuilder();
        int left = 0;
        int right = s.length() - 1;
        while (s.charAt(left) == ' ') {
            left++;
        }

        while (s.charAt(right) == ' ') {
            right--;
        }
        for (int i = left; i <= right; i++) {
            if (i > 0 && s.charAt(i) == ' ' && s.charAt(i - 1) == ' ') {
                continue;
            } else {
                sb.append(s.charAt(i));
            }
        }
        String str = sb.toString();
        char[] chars = str.toCharArray();
        left = 0;
        right = chars.length - 1;
        while (right > left) {
            char temp = chars[left];
            chars[left] = chars[right];
            chars[right] = temp;
            left++;
            right--;
        }
        left = 0;
        right = 0;
        while (right <= chars.length) {
            if (right == chars.length || chars[right] == ' ') {
                int tempLeft = left;
                int tempRight = right - 1;

                while (tempRight > tempLeft) {
                    char temp = chars[tempLeft];
                    chars[tempLeft] = chars[tempRight];
                    chars[tempRight] = temp;
                    tempLeft++;
                    tempRight--;
                }
                right++;
                left = right;
            } else {
                right++;
            }
        }
        return new String(chars);
    }


}

思路是对的,但是代码梳理过程太麻烦了,尤其是在处理单词反转时。可以将每个部分的内容拆分成不同的方法进行调用,代码会更简洁一些。

public static void main(String[] args) {
        String s = "  hello   world   ";
        String res = reverseWords(s);
        System.out.println(res);
    }

    private static String reverseWords(String s) {
        StringBuilder sb = removeSpace(s);
        reverseString(sb, 0, sb.length() - 1);
        reverseEachWord(sb);
        return sb.toString();
    }

    private static void reverseEachWord(StringBuilder sb) {
        int start = 0;
        int end = 0;
        while (end <= sb.length()) {
            while (end < sb.length() && sb.charAt(end) != ' ') {
                end++;
            }
            reverseString(sb, start, end - 1);
            end++;
            start = end;
        }
    }

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

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

** LeetCode 剑指offer58-2. 左旋转字符串 **
题目链接:剑指offer58-2. 左旋转字符串

思路:最直接的思路是通过剪切字符串,用可变字符串实现拼接,但实际上本题目应该是考察的字符串的反转运用。

package str;

/**
 * @author rpstart
 * @create 2023-07-08 11:43
 */
public class reverseLeftWords58 {
    public static void main(String[] args) {
        String s = "abcdefg";
        int n = 2;
        String res = reverseLeftWords(s, n);
        System.out.println(res);
    }

    public static String reverseLeftWords(String s, int n) {
        StringBuilder sb = new StringBuilder();
        sb.append(s.substring(n, s.length()));
        sb.append(s.substring(0, n));
        return sb.toString();
    }
}

从题目考察的角度来进行思考,如何对字符串进行反转,能实现字符串的左旋呢?先对字符串整体进行反转,然后对结果进行前半部分的反转不就实现了吗。那这个题目实际上跟上一道题目是类似的,调用的方法基本一致。

参考思路:在原字符串上进行修改,无需申请额外空间。

private static 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);
        reverseString(sb, 0, len - 1);
        return sb.toString();
    }

    private static void reverseString(StringBuilder sb, int start, int end) {
        while (start <= end) {
            char temp = sb.charAt(end);
            sb.setCharAt(end, sb.charAt(start));
            sb.setCharAt(start, temp);
            start++;
            end--;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值