【代码训练营】day8 344.反转字符串 & 541. 反转字符串II & 剑指Offer 05.替换空格 & 151.翻转字符串里的单词 & 剑指Offer58-II.左旋转字符串

所用代码 java

反转字符串 LeetCode 344

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

思路

双指针直接交换左右两边的字符

public void reverseString(char[] s) {
    int left = 0;
    int right  = s.length - 1;
    // 取不取等都行,因为中间那个数不用交换
    while (left < right){
        // 交换
        char temp = s[right];
        s[right] = s[left];
        s[left] = temp;
        
        // 左右指针向中间靠拢
        left++;
        right--;
    }
}

总结

取不取等不重要,中间那个数不用交换,记得每次操作后左右指针往中间移动一格就行了

反转字符串II LeetCode 541

题目链接:反转字符串II LeetCode 541 - 简单

思路

同第一个一样,只要找到要反转的部分进行反转就好了

public String reverseStr(String s, int k) {
    char[] c = s.toCharArray();
    for (int i = 0; i < c.length; i += 2*k) {

        // 可以翻转k个字符就直接翻转,然后进行下一步
        if (i+k < c.length){
            swap(c,i,i+k-1);
        }else {
            // 否则就是不够k个字符了,直接翻转后面的字符
            swap(c,i,c.length-1);
        }

    /*
        // 剩余字符大于k个,小于2k个
        if (i+2*k > c.length && i+k < c.length){
            swap(c, i, i+k-1);
        }else if(i+k > c.length){ // 剩余字符少于k个
            swap(c,i,c.length-1);
        }else {
            swap(c,i,i+k-1);
        }
    */
    }
    return String.valueOf(c);
}

// 指针所在位置反转,左闭右闭
public void swap(char[] s, int left, int right) {
    while (left < right){
        char temp = s[right];
        s[right] = s[left];
        s[left] = temp;

        left++;
        right--;
    }
}

总结

注意每次循环是跳2k步,每次再判断能不能在k的范围内进行翻转。

剑指Offer 05.替换空格

题目链接:剑指Offer 05.替换空格 - 简单

思路

新建一个StringBuilder,一个一个的添加,遇到空格就添加%20

public String replaceSpace(String s) {
    char[] c = s.toCharArray();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < c.length; i++) {
        if (c[i] == ' '){
            sb.append("%20");
            continue;
        }
        sb.append(c[i]);
    }
    return sb.toString();
}

总结

java的StringBuilder用于添加字符非常的简单,如果使用双指针的话较为复杂,但是思想也很棒,没遇到一个空格,扩容两个空格位(就三个位置),这样就刚好可以存下 %20
left:指向原始数组的最后一个元素
right:指向扩容后数组的最后一个元素

双指针重要代码如下:

//有空格情况 定义两个指针
    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--;
    }

翻转字符串里的单词 LeetCode 151

题目链接:翻转字符串里的单词 LeetCode 151 - 中等

思路

首先去掉首尾空格,然后反转整个字符串,再反转每个单词

    public String reverseWords(String s) {
        // 1、移除首尾和中间的空格
        StringBuilder sb = removeSpace(s);
        // 2、反转整个字符串
        reverseString(sb,0, sb.length()-1);
        // 3、反转各个单词
        reverseEachWord(sb);
        // 返回string
        return sb.toString();

    }

    // 去除首尾空格
    public StringBuilder removeSpace(String s){
        StringBuilder sb = new StringBuilder();
        int start = 0;
        int end = s.length() - 1;
        // 去除首部空格
        while (s.charAt(start) == ' ') start++;
        // 去除尾部空格
        while (s.charAt(end) == ' ') end--;
        while (start <= end){
            char c = s.charAt(start);
            // s的下一位不为空,或者下一个为空(单词直接的空格)但是不能有两个空格
            if(c != ' ' || sb.charAt(sb.length()-1) != ' '){
                sb.append(c);
            }
            start++;
        }
//        System.out.println("去除空格后的字符串:"+sb);
        return sb;
    }

    // 反转整个StringBuilder (左闭右闭)
    public void reverseString(StringBuilder sb,int start, int end){
        while (start < end){
            char temp = sb.charAt(start);
            // sb.setCharAt(int i, "a") 设置i位置的值为a
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
        }
//        System.out.println("反转后的字符串"+sb);
    }

    // 反转其中的单词
    public void reverseEachWord(StringBuilder sb){
        int start = 0;
        int end = 1;
        while (start < sb.length()){
            // 找到单词的末尾,末尾一定是空格,找到了之后end指向下一位(非空格位置)
            while (end < sb.length() && sb.charAt(end) != ' '){
                end++;
            }
            // 该方法为左闭右闭
            reverseString(sb, start, end - 1);
            // 反转完第一个单词,start与end往后移位
            start = end + 1;
            end = start + 1;
        }
//        System.out.println("单词反转:"+sb);
    }

总结

本题知道方法,但是写不出来,看到题解,对各个方法也不是很熟,还要多学习理解各种写法!

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

题目链接:剑指Offer58-II.左旋转字符串 - 简答

思路

先把后面的数存到一个StringBuilder中,再把前面的数存到StringBuilder中

public String reverseLeftWords(String s, int n) {
    StringBuilder sb = new StringBuilder();
    char[] c = s.toCharArray();
    // 先加后面几个数
    for (int i = 0; i < c.length; i++) {
        if (i<n){
            continue;
        }
        sb.append(c[i]);
    }
    // 后加前面几个数
    for (int i = 0; i < n; i++) {
        sb.append(c[i]);
    }

    return sb.toString();
}

总结

看了代码随想录,是先将字符串整体反转,再分步反转,代码如下:

public String reverseLeftWords(String s, int n) {
    char[] c = s.toCharArray();
    int start = 0;
    int end = c.length;
    // 1、翻转整个字符串
    reverse(c, start, end - 1);
    // 2、翻转字符串n前面的buf
    reverse(c, start, end - n - 1);
    // 3、翻转字符串n后面的部分
    reverse(c, end - n, end - 1);

    return String.valueOf(c);
}

// 翻转字符串,左闭右闭
public void reverse(char[] c, int start, int end){
    while (start < end){
        char temp = c[end];
        c[end] = c[start];
        c[start] = temp;

        start++;
        end--;
    }
}

这个操作的和就和前面的其他操作差不多,都是翻转字符串,重点就是:先整体后局部或者先局部后整体

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值