算法修炼之路—【字符串】Leetcode 459 重复的子字符串

题目描述

给定一个非空的字符串,判定它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不会超过10000

示例1:

输入: “abab”
输出: True
解释: 可由子字符串“ab”重复两次构成。

示例2:

输入: “aba”
输出: False

示例3:

输入: “abcabcabcabc”
输出: True
解释: 可由子字符串“abc”重复四次构成,或由子字符串“abcabc”重复两次构成。

思路分析

难度是简单 ,首先就是想到先遍历再存储最后遍历是否为重复字符:

  1. 遍历出标准子字符串subStr假设重复字符串中无重复字符);
  2. 存储至容器中;
  3. 遍历之后的字符串,是否满足等长部分相等;

这时,考虑到需要借助数据容器,我们需要set以判重,由于需要记录顺序,则我们同时借助StringBuilder来存储subStr,此时有代码1

**代码1 子字符串无重复字符 **

    public static boolean solution(String s) {
        if(s.length() < 2) return false;
        
        List<Character> list = new ArrayList<>();
        StringBuilder strBul = new StringBuilder();
        
        int i = 0;
        while(i < s.length()){
            char c = s.charAt(i);
            if(list.contains(c)){
                break;
            }
            list.add(c);
            strBul.append(c);
            i++;
        }
        
        String subStr = strBul.toString();
        
        if(s.length() == subStr.length() || s.length() % subStr.length() != 0)             
            return false;
        
        else{            
            while(i < s.length() && (i+subStr.length()) <= s.length()){
                if(!subStr.equals(s.substring(i, i+subStr.length())))
                    return false;
                i += subStr.length();
            }
        }  
        
        return i == s.length();
    }

此时的时间复杂度为O(n),空间复杂度为O(min(n, l),其中n为字符串长度,l为重复时的子字符串的长度(若存在);

此时,我们会发现,代码1对诸如"abaaba"类本身子字符串带有重复字符的字符串无法进行正确性判断,故这里参考网络解法,其基本思想是当存在重复子字符串时(重复次数>=2),则此时可将原字符串进行2倍扩展并级联doubleS,将首位个除去一个字符后,判断此时是否包含原字符串s,若包含则返回true,否则返回false 。 算法思想很巧妙,笔者也很惭愧,算法之路任重道远~~!

解题代码

    public static boolean solution(String s) {
        String doubleS = s + s;
        if(doubleS.substring(1, doubleS.length()-1).contains(s))
        	return true;
        return false;
    }

复杂度分析

这里我们设n为输入字符串的长度;

时间复杂度: 时间复杂度为O(n);
空间复杂度: doubleS需要2n的空间,故空间复杂度为O(n);

Github源码

完整可运行文件请访问GitHub

©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师: 上身试试 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值