Leetcode 459. Repeated Substring Pattern--判断某字符串是否是某子串重复出现组成的

Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000.

Example 1:

Input: "abab"
Output: True
Explanation: It's the substring "ab" twice.

Example 2:

Input: "aba"
Output: False

Example 3:

Input: "abcabcabcabc"
Output: True
Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.)

 

/**
 * Title:
 *
 * @Author
 * @CreateTime 2019/6/11 14:30
 */
public class Leetcode_459_RepeatedSubstringPattern {

    public boolean repeatedSubstringPattern(String s) {
        char f = s.charAt(0);
        int length = s.length();
        if (length == 1) {//如果只有一个字符则返回false
            return false;
        }

        if (isPrime(length)) {
            for (int i = 1; i < length; i++) {//如果长度是素数,则需要每个字符都相同才能返回true
                if (s.charAt(i) != f) {
                    return false;
                }
            }
            return true;
        }

        for (int div = 2; div <= length / 2; div++) {
            if (length % div == 0) {//能除尽的整数
                int count = 1;
                for (int j = 0; j + div * count < length; j++) {//j按照0,1,2...div-1,0,1,2...div-1..循环,count从1,2,3...不断递增
                    if (j == div) {
                        count++;
                        j = -1;//需要j=0,下一步执行j++,所以此时需要j=-1
                        continue;
                    }
                    if (s.charAt(j) == s.charAt(j + div * count)) {
                        if (j + div * count == length - 1) {//比较到结尾时则返回true
                            return true;
                        }
                    } else {
                        if (div == length / 2) {
                            return false;
                        }
                        break;//会跳出本层for循环,本层for循环外的if条件不会被跳出
                    }
                }
            }//if
        }//for
        return true;
    }

    public boolean isPrime(int length) {
        for (int i = 2; i <= Math.sqrt(length); i++) {
            if (length % i == 0) {
                return false;//不是素数
            }
        }
        return true;//是素数
    }


    public static void main(String[] args) {
        Leetcode_459_RepeatedSubstringPattern object = new Leetcode_459_RepeatedSubstringPattern();
//        System.out.println(object.isPrime(11));
//        System.out.println(object.isPrime(21));
//        System.out.println(object.repeatedSubstringPattern("abcabcabc"));//true
//        System.out.println(object.repeatedSubstringPattern("abcabcabca"));//false
//        System.out.println(object.repeatedSubstringPattern("abcdabcd"));//true
//        System.out.println(object.repeatedSubstringPattern("abcdabce"));//true
        System.out.println(object.repeatedSubstringPattern("ababba"));//true
    }
}

Runtime: 24 ms, faster than 49.63% of Java online submissions for Repeated Substring Pattern.

Memory Usage: 37.9 MB, less than 99.88% of Java online submissions for Repeated Substring Pattern.

【关于break的使用可见Java,break与continue区别(二)】

 

Discussion中有一种更精辟的方法:

class Solution {
    

    // [a b] [a b] : given a string with repeated pattern
    // [a b] [a b] [a b] [a b] : double it
    // b [a b] [a b] a : break first and last chunk
    // The final string should contain original string
    
    // [a b c] : given a string without repeated pattern
    // [a b c] [a b c] : double it
    // b c a b : break first and last chunk
    // The final string does not contain original string

    public boolean repeatedSubstringPattern(String s) {
        String s2 = s + s;
        return s2.substring(1, s2.length() - 1).contains(s);
    }
}

Runtime: 29 ms, faster than 40.31% of Java online submissions for Repeated Substring Pattern.

Memory Usage: 37.1 MB, less than 100.00% of Java online submissions for Repeated Substring Pattern.

你可能感兴趣的:(算法,Java)