LeetCode Repeated Substring Pattern

本文探讨了LeetCode上的一道题目:重复子字符串模式。提供了两种解决方案:一种是通过尝试不同长度的子字符串来检查整个字符串是否由多个相同的子字符串组成;另一种是使用类似于KMP算法的方法来提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题链接在这里:https://leetcode.com/problems/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.)

题解:

若是str能被拆能n个重复的子串, 那么每个子串的长度不会超过str.length()/2. 从str.length()/2到1长度,挨个试取字串拼回去,看是否等于原串.

Time Complexity: O(n^2). 拆成n/2, 拼回去用时2, 拆成n/3, 拼回去用时3, ..., 总用时(2+3+4+...+n), n = str.length().

Space: O(1). 

AC Java:

 1 public class Solution {
 2     public boolean repeatedSubstringPattern(String str) {
 3         int len = str.length();
 4         for(int i = len/2; i>=1; i--){
 5             if(len%i == 0){
 6                 String template = str.substring(0, i);
 7                 StringBuilder sb = new StringBuilder();
 8                 int n = len/i;
 9                 while(n-->0){
10                     sb.append(template);
11                 }
12                 if(sb.toString().equals(str)){
13                     return true;
14                 }
15             }
16         }
17         return false;
18     }
19 }

可采用类似KMP的算法. 这里的next不再是当前char之前的最大相同前缀后缀,而是包含当前char的最大相同前缀后缀. e.g "abcabcabc", next = [0,0,0,1,2,3,4,5,6].

看str.length()能否被str.length() - next[next.length-1]整除.

Time Complexity: O(str.length()). Space: O(str.length()).

AC Java:

 1 public class Solution {
 2     public boolean repeatedSubstringPattern(String str) {
 3         if(str == null || str.length() == 0){
 4             return true;
 5         }
 6         int len = str.length();
 7         int [] next = new int[len];
 8         getNext(str, next);
 9         int preLen = next[next.length-1];
10         return (preLen>0 && len%(len-preLen) == 0);
11     }
12     
13     private void getNext(String s, int [] next){
14         int len = s.length();
15         int p = 0;
16         int q = 1;
17         while(q < len){
18             //s.charAt(p)表示前缀. s.charAt(q)表示后缀
19             if(s.charAt(p) == s.charAt(q)){
20                 next[q] = p+1;
21                 p++;
22                 q++;
23             }else if(p == 0){
24                 next[q] = p;
25                 q++;
26             }else{
27                 p = next[p-1];
28             }
29         }
30     }
31 }

类似Implement strStr().

转载于:https://www.cnblogs.com/Dylan-Java-NYC/p/6321786.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值