Google 面试题 | 判断字符串是否可由重复子字符串组成

2024-05-26 22:32

本文主要是介绍Google 面试题 | 判断字符串是否可由重复子字符串组成,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

对于一个非空字符串,判断其是否可由一个子字符串重复多次组成。字符串只包含小写字母且长度不超过10000。

样例1

  • 输入: “abab”
  • 输出: True
  • 样例解释: 输入可由”ab”重复两次组成

样例 2

  • 输入: “aba”
  • 输出: False

样例 3

  • 输入: “abcabcabcabc”
  • 输出: True
  • 样例解释:输入可由”abc”重复四次组成

解题思路

1. 一个简单的思路

枚举子字符串的长度lenSub < len(len为原字符串长度),将原字符串分成多个子字符串,每个子字符串长度为lenSub(由此可见,lenSub整除len),再判断这些子字符串是否全部相等,若全部相等,则返回True,如果对于所有lenSub均不满足该条件,则返回False。时间复杂度为O(len*v(len)),其中v(len)为len的因数个数(因为我们只需要对整除len的lenSub进行进一步判断)。

2. 下面再说一种神奇的方法

由kmp算法中的next数组实现。

  1. 字符串s的下标从0到n-1,n为字符串长度,记s(i)表示s的第i位字符,s(i,j)表示从s的第i位到第j位的子字符串,若i>j,则s(i,j)=””(空串)。

  2. next数组的定义为:next(i)=p,表示p为小于i且满足s(0 , p) = s(i-p , i)的最大的p,如果不存在这样的p,则next(i) = -1,显然next(0) = -1。我们可以用O(n)的时间计算出next数组。假设我们已知next(0),next(1),……,next(i-1) ,现在要求next(i),不妨设next(i-1) = j0,则由next数组定义可知s(0 , j0) = s(i-1-j0 , i-1)。

    • 若s(j0+1) = s(i),则结合s(0 , j0) = s(i-1-j0 , i-1)可知s(0 , j0+1) = s(i - (j0+1) , i),由此可知,next(i)=j0+1。

    • 若s(j0+1)!=s(i)但s(next(j0)+1)=s(i),记j1=next(j0),则s(j1+1)=s(i),由next数组的定义,s(0 , j1) = s(j0 - j1 , j0) = s(i - 1 - j1 , i - 1),即s(0,j1) = s(i - 1 - j1 , i - 1),由假设s(j1+1) = s(i),则s(0 , j1+1) = s(i - (j1+1) , i),故next(i) = j1+1。

    • 同前两步的分析,如果我们能找到一个k,使得对于所有小于k的k0,s(j(k0)+1)!=s(i),但有s(j(k)+1) = s(i),则由next数组的定义可以得到next(i)=j(k)+1,否则需进一步考虑j(k+1) = next(j(k)),如果我们找不到这样的k,则next(i)=-1。

  3. 对于字符串s,如果j满足,0<=j<=n-1,且s(0,j) = s(n-1-j,n-1),令k=n-1-j,若k整除n,不妨设n=mk,则s(0,(m-1)k - 1) = s(k,mk - 1),即s(0,k-1) = s(k,2k-1) = …… = s((m-1)k - 1,mk - 1),即s满足题设条件。故要判断s是否为重复子串组成,只需找到满足上述条件的j,且k整除n,即说明s满足条件,否则不满足。

  4. 利用已算出的next(n-1),令k=n-1-next(n-1),由c可知,若k整除n,且k < n,则s满足条件,否则不满足。上述算法的复杂度可证明为O(n)。

参考代码

参考代码给出了利用next数组求解的代码。来自九章算法答案

public class Solution {public boolean repeatedSubstringPattern(String s) {int l = s.length();int[] next = new int[l];next[0] = -1;int i, j = -1;for (i = 1; i < l; i++) {while (j >= 0 && s.charAt(i) != s.charAt(j + 1)) {j = next[j];}if (s.charAt(i) == s.charAt(j + 1)) {j++;}next[i] = j;}int lenSub = l - 1 - next[l - 1];return lenSub != l && l % lenSub ==0;}
}

面试官角度分析

这道题的第一种解法比较简单,考察穷举和字符串处理的能力,给出第一种方法并正确分析时间复杂度基本可以达到hire;如果面试者对KMP算法有了解,可以给出第二种next数组的算法可以达到strong hire。

本文来自九章算法公众号 Google 面试题 | 重复子字符串模式

这篇关于Google 面试题 | 判断字符串是否可由重复子字符串组成的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1005772

相关文章

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet

Java使用正则提取字符串中的内容的详细步骤

《Java使用正则提取字符串中的内容的详细步骤》:本文主要介绍Java中使用正则表达式提取字符串内容的方法,通过Pattern和Matcher类实现,涵盖编译正则、查找匹配、分组捕获、数字与邮箱提... 目录1. 基础流程2. 关键方法说明3. 常见场景示例场景1:提取所有数字场景2:提取邮箱地址4. 高级

Python 字符串裁切与提取全面且实用的解决方案

《Python字符串裁切与提取全面且实用的解决方案》本文梳理了Python字符串处理方法,涵盖基础切片、split/partition分割、正则匹配及结构化数据解析(如BeautifulSoup、j... 目录python 字符串裁切与提取的完整指南 基础切片方法1. 使用切片操作符[start:end]2

MyBatis的xml中字符串类型判空与非字符串类型判空处理方式(最新整理)

《MyBatis的xml中字符串类型判空与非字符串类型判空处理方式(最新整理)》本文给大家介绍MyBatis的xml中字符串类型判空与非字符串类型判空处理方式,本文给大家介绍的非常详细,对大家的学习或... 目录完整 Hutool 写法版本对比优化为什么status变成Long?为什么 price 没事?怎

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用