算法笔记|Day8字符串II

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

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

题目分析

1.此题需要完成三个步骤:移除多余空格,将整个字符串反转,将每个单词反转;
2.移除空格需要注意:首尾的空格应删掉,每两个单词之间要保留一个空格,同时为了保证删去多余的元素,应该对数组重新resize;
3.时间复杂度为O(n),空间复杂度为O(1)。

代码

class Solution {
    public String reverseWords(String s) {
        char ch[]=s.toCharArray();
        ch=removeSpaces(ch);
        reverse(ch,0,ch.length-1);
        reverseEachWord(ch);
        return new String(ch);
    }

    public char[] removeSpaces(char[] ch){
        int slow=0,fast=0;
        for(;fast<ch.length;fast++){
            if(ch[fast]!=' '){
                if(slow!=0){
                    ch[slow]=' ';
                    slow++;
                }
                while(fast<ch.length&&ch[fast]!=' '){
                    ch[slow]=ch[fast];
                    slow++;
                    fast++;
                }
            }
        }
        char newch[]=new char[slow];//相当于resize
        for(int index=0;index<slow;index++){
            newch[index]=ch[index];
        }
        return newch;
    }
    
    public void reverseEachWord(char[] ch){
        int left=0,right=0;
        for(;right<=ch.length;right++){
            if(right==ch.length||ch[right]==' '){
                reverse(ch,left,right-1);
                left=right+1;
            }
        }
    }
    
    public void reverse(char[] ch,int left,int right){
        while(left<right){
            char temp=ch[left];
            ch[left]=ch[right];
            ch[right]=temp;
            left++;
            right--;
        }
    }
}

☆☆☆☆kamacoder 55. 右旋字符串(待补充)

题目链接:kamacoder 55. 右旋字符串

题目分析

代码


☆☆☆☆☆leetcode 28. 实现 strStr()

题目链接:leetcode 28. 实现 strStr()

题目分析

1.本题为KMP经典题目,其思想为:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配;
2.前缀表(next数组)是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配,其第i个元素为记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀;
3.时间复杂度为O(n + m),空间复杂度为O(m)。

代码

class Solution {
    public int strStr(String haystack, String needle) {
        int next[]=new int[needle.length()];
        getNext(needle,next);
        int j=0;
        for(int i=0;i<haystack.length();i++){
            while(j>0&&needle.charAt(j)!=haystack.charAt(i))
                j=next[j-1];
            if(needle.charAt(j)==haystack.charAt(i))
                j++;
            if(j==needle.length())
                return i-needle.length()+1;        
        }
        return -1;
    }

    private void getNext(String s,int[] next){
        int j=0;
        next[0]=0;
        for(int i=1;i<s.length();i++){
            while(j>0&&s.charAt(j)!=s.charAt(i))
                j=next[j-1];
            if(s.charAt(j)==s.charAt(i))
                j++;
            next[i]=j;
        }
    }
}

☆☆☆☆☆leetcode 459.重复的子字符串

题目链接:leetcode 459.重复的子字符串

题目分析

1.本题可以用字符串匹配的方法,判断s+s拼接的字符串中间是否出现一个s的的时候,注意需要刨除s+s的首字符和尾字符,这样避免在s+s中搜索出原来的s,我们要搜索的是中间拼接出来的s,此方法可以用到库函数,但时间复杂度较高;
2.本题还可以考虑KMP方法,数组长度减去最长相同前后缀的长度相当于是第一个周期的长度,也就是一个周期的长度,如果这个周期可以被整除,就说明整个数组就是这个周期的循环,即返回true,否则返回false;
3.时间复杂度为O(n),空间复杂度为O(n)。

代码

1.字符串匹配的方法
class Solution {
    public boolean repeatedSubstringPattern(String s) {
        String t = s + s;  
        t = t.substring(1, t.length() - 1); // 掐头去尾  
        if (t.contains(s)) 
            return true;  
        return false;  
    }
}
2.KMP方法
class Solution {
    public boolean repeatedSubstringPattern(String s) {
        int len=s.length();
        int next[]=new int[len];
        int j=0;
        next[0]=0;
        for(int i=1;i<s.length();i++){
            while(j>0&&s.charAt(j)!=s.charAt(i))
                j=next[j-1];
            if(s.charAt(j)==s.charAt(i))
                j++;
            next[i]=j;
        }
        if(next[len-1]>0&&len%(len-next[len-1])==0)
            return true;
        return false;
    }
}
  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值