海智算法训练营第七天 | 第四章 字符串part01 | 344反转字符串 541反转字符串II 卡码网:54替换数字 151翻转字符串里的单词 卡码网:55右旋转字符串

学习目标:

1.利用对撞指针反转字符数组

2.反转字符串2

3.替换数字

4.反转字符串中的单词

5.右旋转字符串

 1.利用对撞指针反转字符数组

题目:反转字符串

创建两个指针分别从字符数组两端向中间遍历交换,这里用了异或交换,字符交换用异或比较合适,但如果碰到了数据较大的float类型的整形数字,就不能随便用异或交换了,还是老老实实创建变量吧。

class Solution {
    public void reverseString(char[] s) {
        int l = 0 ,  r = s.length-1;
        while(l<r){
            s[l] ^= s[r];
            s[r] ^= s[l];
            s[l] ^= s[r];
            l++;
            r--;
        }
    }
}

2.反转字符串2

题目:反转字符串2

第一种自己写的方法:我首先定义了两个指针作为移动窗口的区间,他们的差值是2k,定义循环的次数是数组的长度除于2k,每次循环两个指针都+2k,然后每次在这个区间里面切割字符串并反转,定义res字符串每次处理完区间内的字符串就加进去。


class Solution {
    public static String reverseStr(String s, int k) {
        int l = 0;
        int r = l + 2 * k;
        int len = s.length() / (2 * k);
        String res = "";
        while (len-- > 0) {
            String temp = s.substring(l, l + k);
            StringBuffer sb = new StringBuffer(temp);
            res += sb.reverse() + s.substring(l + k, r);
            l += 2 * k;
            r += 2 * k;
        }
        if (s.length() - l < k)
            res += new StringBuffer(s.substring(l)).reverse();
        else if (s.length() - l < 2 * k && s.length() - l >= k) {
            StringBuffer sb = new StringBuffer(s.substring(l, l + k));
            res += sb.reverse() + s.substring(l + k);
        }
        return res;
    }
}

自己写的方法非常麻烦,并且很容易就乱,在看了答案的处理方法后,我发现解法1的处理方法和我一样,但是解法二运用对撞指针的解法非常易懂简洁:

答案中的思路是左指针每次走2k,然后前k个互换,如果不够k个就全部互换,Math.min(ch.length - 1, start + k - 1);这句代码非常妙,如果遍历到后面发现k个不够了,那么就将后面所有的数都互换。

class Solution {
    public String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        for(int i = 0; i < ch.length; i += 2 * k){
            int start = i;
            //这里是判断尾数够不够k个来取决end指针的位置
            int end = Math.min(ch.length - 1, start + k - 1);
            //用异或运算反转 
            while(start < end){
                ch[start] ^= ch[end];
                ch[end] ^= ch[start];
                ch[start] ^= ch[end];
                start++;
                end--;
            }
        }
        return new String(ch);
    }
}

3.替换数字

题目:替换数字

在java中这类题较简单,只需要定义一个StringBuffer对象就可以缓冲字符串,只需要判断是不是数字就好了:  s.charAt(i) >= '0' && s.charAt(i) <= '9'  ,答案不是用这个,但是我用这个比较好理解。

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) >= '0' && s.charAt(i) <= '9') {
                sb.append("number");
            }else sb.append(s.charAt(i));
        }
        System.out.println(sb);
    }
}

4.反转字符串中的单词

我靠真写的快爆炸了,这题花了有两个小时一直在报错调试。先说说思路是什么样的吧,反转整个字符串,再把每个单词也反转,利用双指针把空格删掉,就可以完成了。

题目:反转字符串中的单词

真的好难啊!但是自我感觉比答案写的要好。


class Solution {


    public  String reverseWords(String s) {
       //双指针去空格
        char[] chars = s.toCharArray();
        StringBuffer res = new StringBuffer();
        int fast = 0;
        int slow = 0;
        while (fast < chars.length) {
            if(chars[fast] == ' ') fast++;
            else{
                if(slow != 0)res.append(' ');
                while(fast < chars.length && chars[fast] != ' '){
                    res.append(chars[fast++]);
                    slow++;
                }
            }
        }

        res.reverse();
        int l = 0,r = 0;
        while(r <= res.length()){
            if(r==res.length() ||res.charAt(r)==' '){
                int tempR =r;
                while(l < r-1){
                    char temp = res.charAt(l);
                    res.setCharAt(l,res.charAt(r-1));
                    res.setCharAt(r-1,temp);
                    l++;
                    r--;
                }
                l = tempR+1;
                r = tempR+1;
            }
            r++;
        }
        return res.toString();
    }
}

5.右旋转字符串

题目:右旋转字符串

这道题其实可以用java中的subString方法直接秒掉,但是学一下这题反转字符串的思路,也是先翻转所有,再反转部分,跟上题的思路大差不差。

下面的模板方法区间翻转字符串倒是可以记一下!

class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String s = sc.next();
        char[] chars = s.toCharArray();
        reverseString(chars,0, chars.length-1);
        reverseString(chars,0,n-1);
        reverseString(chars,n, chars.length-1);
        System.out.println(new String(chars));
    }


    public static void reverseString(char[] ch, int start, int end) {
        while(start < end){
            ch[start] ^= ch[end];
            ch[end] ^= ch[start];
            ch[start] ^= ch[end];
            start++;
            end--;
        }
    }
}

学习时长:4h

总结:这一章节学会了字符串的各个花式翻转操作,对字符串的翻转理解更加深刻,也对双指针降低翻转的复杂度更加熟悉,继续加油。

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值