代码随想录一刷(day08) |344.反转字符串|541. 反转字符串II|151.翻转字符串里的单词|右旋字符串

344.反转字符串 leetcode链接

思考

将字符串看作一个数组,我们不难想到在 反转数组 那道题的做法,使用双指针的方法可以在时间复杂度为O(n)空间复杂度为O(1)

代码展示

    public void reverseString(char[] s) {
        int i;
        int j;
        char temp;
        for (i = 0,j = s.length - 1; i < s.length / 2; i++,j--) {
            temp = s[i];
            s[i]=s[j];
            s[j] = temp;
        }
        for (int k = 0; k < s.length; k++) {
            System.out.print(s[k]+"\t");
        }
    }

总结

本题考察了对字符串的最基本的翻转操作,并且在后面会常常用到此类操作,应牢记掌握

541. 反转字符串II leetcode链接

思考

本题在上一题反转函数的基础上添加了局部反转的特性即反转的目标变成了不固定的一段子字符串。我们可以通过编写一个方法来解决局部反转的问题,并且要向该方法中传入三个参数,分别为:字符串,起始下标,终止下标。每次满足反转的条件时就进行反转

代码展示

    public String reverseStr(String s, int k) {
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i+=2*k) {
            if (i + k <= chars.length){
                reserve(chars,i,i+k-1);
                continue;
            }
            reserve(chars,i,chars.length - 1);
        }
        return new String(chars);
    }
    public void reserve(char[] ch,int i,int j){
        char temp;
        for (; i < j; i++,j--) {
            temp = ch[i];
            ch[i] = ch[j];
            ch[j] = temp;
        }
    }

总结

本题是在反转链表的基础上加了一个反转的区间,只需做出一个函数完成局部反转,再明确题目要求在什么时候反转即可。在该题中的reserve方法在后续的题目中也会经常充当一个辅助方法的身份,需要熟练掌握

151.翻转字符串里的单词 leetcode链接

思考

先去除去字符串中多余的空格,这里可以使用快慢指针在原数char组上进行修改,使用快指针在前面遍历,如果遇到空格就跳过,如果不是空格并且慢指针没有指在0下标处时,就领慢指针指向的位置的字符变为空格,并让slow++,然后再进入while循环,直到char[fast]为空格,这时跳出while循环,直到遍历完所有单词。在这之后将字符串进行整体的反转,之后再将字符串中的每个单词进行反转,即可得出答案

代码展示

    public static String reverseWords(String s) {
        String s1 = reserveStr(s); //反转整个字符串
        String s2 = removeExtraSpaces(s1); //删去多余的空格
        String s3 = reaerveEachWord(s2); //反转每个单词
        return s3;
    }
    public static String removeExtraSpaces(String str){

        char[] charArray = str.toCharArray();
        int fast = 0;
        int slow = 0;
        for (; fast < charArray.length; fast++) {
            if (charArray[fast]!=' '){
                if (slow != 0)
                    charArray[slow++] = ' ';
                //遍历完一个单词
                while (fast < charArray.length && charArray[fast] != ' ')
                    charArray[slow++] = charArray[fast++];
            }
        }
        char[] newChars = new char[slow];
        System.arraycopy(charArray, 0, newChars, 0, slow);
        return String.valueOf(newChars);
    }

    public static String reserveStr(String str){
        char[] chars = str.toCharArray();
        char temp;
        int i;
        int j;
        for (i = 0,j = chars.length - 1; i < chars.length / 2; i++,j--) {
            temp = chars[i];
            chars[i] = chars[j];
            chars[j] = temp;
        }
        return String.valueOf(chars);
    }
    public static String reaerveEachWord(String str){
        char[] chars = str.toCharArray();
        int floag = 0;
        for (int i = 0; i <= chars.length; i++) {
            if (i == chars.length||chars[i]==' ' ){//此处使用短路或可以避免数组越界异常,判断的顺序不能变
                reserve(chars,floag,i - 1);
                floag = i + 1;
            }
        }
        return String.valueOf(chars);
    }
    public static void reserve(char[] ch,int i,int j){
        char temp;
        for (; i < j; i++,j--) {
            temp = ch[i];
            ch[i] = ch[j];
            ch[j] = temp;
        }
    }

总结

本题中使用到的三个方法都是以前使用过的,尤其是其中反转整个字符串和局部反转字符串在前两题就写过。而快慢指针则在前面的 数组-移除元素 以及 删除链表中倒数第n个节点 中使用过,不难看出,在进行删除元素的时候考虑快慢指针还是一个不错的选择的

右旋字符串 卡码网链接

思考

可以根据n将字符数组分为两部分,先对字符数组整体进行反转,在对字符串中的两部分分别进行反转,从而得出答案

代码展示

    public static String rightTurnString(String str,int num){
        String reserveAll = reserveAll(str);
        char[] chars = reserveAll.toCharArray();
        int start = 0;
        for (int i = 0; i <= chars.length; i++) {
            if (i == num || i == chars.length){
                reserveLocal(chars,start,i - 1);
                start = i;
            }
        }
        return String.valueOf(chars);
    }

    //反转整个字符串
    public static String reserveAll(String str){
        char[] chars = str.toCharArray();
        int i;
        int j;
        char temp;
        for (i = 0,j = chars.length - 1; i < chars.length / 2; i++,j--) {
            temp = chars[i];
            chars[i] = chars[j];
            chars[j] = temp;
        }
        return String.valueOf(chars);
    }
    //局部反转
    public static void reserveLocal(char[] ch,int start,int end){
        char temp;
        for (; start < end; start++,end--) {
            temp = ch[start];
            ch[start] = ch[end];
            ch[end] = temp;
        }
    }

总结

本题的要点在于抓住题中的有效信息从而得出解法,根据本题题干中的后面 k 个字符移到字符串的前面可以推断出本题势必会用到字符串的局部反转,然而仅仅局部反转是不够的,毕竟本题最终将字符串后面的一部分移到前面,这就可以联想到上一题,反转单词,从而得出本题解法,依然是结合字符串的整体反转和局部反转解题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值