leetcode 459. Repeated Substring Pattern

来源:互联网 发布:视频录制软件电脑 编辑:程序博客网 时间:2024/06/13 11:27

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: TrueExplanation: It's the substring "ab" twice.

Example 2:

Input: "aba"Output: False

Example 3:

Input: "abcabcabcabc"Output: TrueExplanation: It's the substring "abc" four times. (And the substring "abcabc" twice.)
注意这道题不能用递归,不然会stack overflow。

  1. 重复字符串的长度 一定是整个字符串长度 的除数
  2. 找到 str.length 的所有可能的除数,从length/2 来开始找。
  3. 如果 i 是 str.length 的除数,那么重复叠加子字符串直到长度和s.length 相等为止。
  4. 如果获得的字符串和输入的 str 相等,返回true 。

public boolean repeatedSubstringPattern(String s) {int n=s.length();for(int sub_len=s.length()/2;sub_len>=1;sub_len--){if(n%sub_len==0){int times=n/sub_len;String subString=s.substring(0,sub_len);StringBuilder sb=new StringBuilder();for(int i=0;i<times;i++){sb.append(subString);}if(sb.toString().equals(s)){return true;}}}return false;}
还有大神用了一种很奇妙的思路:

假设输入是 S="helloworld". 现在给了另外一个字符串 T="lloworldhe", 我们如何确认 T 是 S 旋转后的一个版本?可以检查 S 是否是of T+T 的子串。

那么我们如何将这个结论应用到该问题上呢?我们假设 S 的每个旋转版本,比如假设它旋转了从左开始的 k 个单元 [k < len(S)] ,确切地说,我们看这些字符串 "elloworldh", "lloworldhe", "loworldhel", 等等...

如果我们要判断一个周期性的字符串 (i.e. is made up of strings that are the same and repeat R times), 那么我们可以检查是否 该字符串 和 它的某个旋转版本 是一样的。如果存在,那么这个字符串是周期性的。检查 S 是否是 (S+S)[1:-1] (意思是S+S去掉头字符和尾字符) 的子串。

如果 S 由重复子串组成,那么可以被表示为 S = AA (比如,这里 S 有两个重复子串)
那么我们重复 S, SS=AAAA.
去掉第一个字符和最后一个字符,我们产生一个新字符串: S2=XAAY.

如果该字符串是由重复子串组成,那么S2 中应该包含 S 。

public boolean repeatedSubstringPattern(String s) {        String c = (s + s).substring(1, s.length() + s.length() - 1);        return c.indexOf(s) != -1;}

还有大神用KMP做。


n-len: the length of prefix(should be the repeated sequence),
n%(n-len): check if the candidate sequence is the answer.

public boolean repeatedSubstringPattern(String str) {//This is the kmp issueint[] prefix = kmp(str);int len = prefix[str.length()-1];int n = str.length();return (len > 0 && n%(n-len) == 0);}private int[] kmp(String s){int len = s.length();int[] res = new int[len];char[] ch = s.toCharArray();int i = 0, j = 1;res[0] = 0;while(i < ch.length && j < ch.length){     if(ch[j] == ch[i]){          res[j] = i+1;          i++;          j++;     }else{          if(i == 0){               res[j] = 0;               j++;          }else{               i = res[i-1];          }     }}return res;}

KMP详见:http://jakeboxer.com/blog/2009/12/13/the-knuth-morris-pratt-algorithm-in-my-own-words/

我觉得KMP问题肯定之后有更加典型的leetcode题,因此我这里就不详细解释了。