【Leecode】代码随想录字符串篇day9(字符串旋转&KMP)

字符串旋转

反转单词

  • 题目链接:反转字符串中单词
  • 我的解法:天知道我为什么把创建新字符串累加空格分割得字符串写的这么麻烦,还在结尾出空格纠结了那么久。。。
class Solution {
    public String reverseWords(String s) {
        int len = s.length();
        int start = len - 1; int end = len - 1;
        String str = "";int flag = 0;
        while(start >= 0)
        {
            while(end >= 0 && s.charAt(end) == ' ') {end--;start--;}
            // System.out.print(start);
            // System.out.println(end);
            while(start >= 0 && s.charAt(start) != ' ') start--;
            if(end >= 0)
            {
                if(flag != 0) str += ' ';
                else flag = 1;
                start++;
                int wordLen = end - start + 1;
                while(start <= end) 
                {
                    str += s.charAt(start);
                    start++;
                }
                end -= wordLen;
                start = end;
            }
        }
        return str;
    }
}

总结:我觉得不算水题,难点其实在于一不小心数组会越界,下次就知道,空格直接加,最后用new String(string.toCharArray(),0,string.length()-1);截取即可,注意这里截取的是字符数组。

  • 复杂度:时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 2 n ) O(2n) O(2n)

  • 拓展解法:去空格-反转-再内部反转

class Solution {
    public String reverseWords(String s) {
        //转换为字符数组
        char[] str = s.toCharArray();
        //去除多余空格
        str = removeExtraSpace(str);
        //转置整个字符串
        reverseAll(str, 0, str.length - 1);
        //转置每个空格分隔的单词
        reverseWord(str);
        return new String(str);
    }
    public char[] removeExtraSpace(char[] str){
        //参考去除多余元素
        int low = 0;
        for(int fast = 0; fast < str.length; fast++)
        {
            if(str[fast] == ' ') continue;
            else{
                if(low != 0) str[low++] = ' ';//除u第一个加入的word外都加 间隔
                while(fast < str.length && str[fast] != ' ')
                    str[low++] = str[fast++];//这里要一次性加入,不然就会除了第一个字符外全是空格
            }
        }
        //得到没有多余空格的全新数组
        char[] newChar = new char[low];
        System.arraycopy(str, 0, newChar, 0, low);
        System.out.println(new String(newChar));
        return newChar;
    }

    public void reverseAll(char[] str, int left, int right){
        if(right >= str.length) return;//为了方便单词级反转
        //参考反转字符串Ⅰ
        while(left < right)
        {
            char tmp = str[left];
            str[left] = str[right];
            str[right] = tmp;
            left++;
            right--;
        }
    }

    private void reverseWord(char[] str){
        //参考反转字符串Ⅱ
        int start = 0; 
        for(int end = 0; end <= str.length; end++)
        {
            /*end在空格和结尾处反转,两条件有先后顺序避免越界*/
            if(end == str.length || str[end] == ' ')
                {reverseAll(str, start, end - 1);
                start = end + 1;}
        }
    }
}

总结:反转字符串一定要联想模板,融汇贯通还不够

  • 复杂度:时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 2 n ) O(2n) O(2n)

右旋字符串

  • 题目链接:右旋字符串
  • 我的解法:写完上题这题简直不要太简单haha
import java.util.*;
import java.io.*;

public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int k = in.nextInt();
        String s = in.next();
        int len = s.length();
        //System.out.print(s);
        if(k >= len) {System.out.print(s); return;}
        char[] str = s.toCharArray();
        //全部反转
        reverse(str, 0, len - 1);
        //反转0 ~ k-1
        reverse(str, 0, k-1);
        //反转k ~ 末尾
        reverse(str, k, len - 1);
        System.out.print(new String(str));
    }
    public static void reverse(char[] str, int start, int end)
    {
        while(start < end)
        {
            char tmp = str[start];
            str[start] = str[end];
            str[end] = tmp;
            //这里一定要及时更新下标
            start++;
            end--;
        }
    }
}

总结:但凡字符串原地旋转的问题一定要联想反转字符串模板,做题之前先想想有没有相关模板,别上来就暴力

  • 复杂度:时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 2 n ) O(2n) O(2n)

KMP

既然可以跳过,那本部分先占坑。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值