当前位置: 首页 > news >正文

信誉好的江苏网站建设资阳公司短视频优化服务

信誉好的江苏网站建设,资阳公司短视频优化服务,凡科互联网,seo专员工资一般多少题目 给定一个非空的字符串#xff0c;判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母#xff0c;并且长度不超过10000。 示例 1: 输入: abab 输出: True 解释: 可由子字符串 ab 重复两次构成。示例 2: 输入: 判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母并且长度不超过10000。 示例 1: 输入: abab 输出: True 解释: 可由子字符串 ab 重复两次构成。示例 2: 输入: aba 输出: False示例 3: 输入: abcabcabcabc 输出: True 解释: 可由子字符串 abc 重复四次构成。 (或者子字符串 abcabc 重复两次构成。)思路 暴力的解法 就是一个for循环获取 子串的终止位置 然后判断子串是否能重复构成字符串又嵌套一个for循环所以是O(n^2)的时间复杂度。 有的同学可以想怎么一个for循环就可以获取子串吗 至少得一个for获取子串起始位置一个for获取子串结束位置吧。 其实我们只需要判断以第一个字母为开始的子串就可以所以一个for循环获取子串的终止位置就行了。 而且遍历的时候 都不用遍历结束只需要遍历到中间位置因为子串结束位置大于中间位置的话一定不能重复组成字符串。 主要讲一讲移动匹配 和 KMP两种方法。 移动匹配 当一个字符串sabcabc内部由重复的子串组成那么这个字符串的结构一定是这样的 也就是由前后相同的子串组成。 那么既然前面有相同的子串后面有相同的子串用 s s这样组成的字符串中后面的子串做前串前面的子串做后串就一定还能组成一个s如图 当然我们在判断 s s 拼接的字符串里是否出现一个s的的时候要刨除 s s 的首字符和尾字符这样避免在ss中搜索出原来的s我们要搜索的是中间拼接出来的s。 以上证明的充分性接下来证明必要性 如果有一个字符串s在 s s 拼接后 不算首尾字符如果能凑成s字符串说明s 一定是重复子串组成。 如图字符串s图中数字为数组下标在 s s 拼接后 不算首尾字符中间凑成s字符串。 图中因为中间拼接成了s根据红色框 可以知道 s[4] s[0] s[5] s[1] s[0] s[2], s[1] s[3] s[2] s[4] ,s[3] s[5] 以上相等关系我们串联一下 s[4] s[0] s[2] s[5] s[1] s[3] 即s[4],s[5] s[0],s[1] s[2],s[3] 说明这个字符串是由 两个字符 s[0] 和 s[1] 重复组成的 如图 s[3] s[0]s[4] s[1] s[5] s[2]s[0] s[3]s[1] s[4]s[2] s[5] 以上相等关系串联 s[3] s[0] s[1] s[4] s[2] s[5] s[0] s[1] s[2] s[3] s[4] s[5] 和以上推导过程一样最后可以推导出这个字符串是由 s[0] s[1] s[2] 重复组成。 如果是这样的呢如图 s[1] s[0]s[2] s[1] s[3] s[2]s[4] s[3]s[5] s[4]s[0] s[5] 以上相等关系串联 s[0] s[1] s[2] s[3] s[4] s[5] 最后可以推导出这个字符串是由 s[0] 重复组成。 以上 充分和必要性都证明了所以判断字符串s是否由重复子串组成只要两个s拼接在一起里面还出现一个s的话就说明是由重复子串组成。 代码如下 class Solution { public: bool repeatedSubstringPattern(string s) { string t s s; t.erase(t.begin()); t.erase(t.end() - 1); // 掐头去尾 if (t.find(s) ! std::string::npos) return true; // r return false; } }; 时间复杂度: O(n) 空间复杂度: O(1)不过这种解法还有一个问题就是 我们最终还是要判断 一个字符串s s是否出现过 s 的过程大家可能直接用containsfind 之类的库函数 却忽略了实现这些函数的时间复杂度暴力解法是m * n一般库函数实现为 O(m n)。 充分性证明 如果一个字符串s是由重复子串组成那么 最长相等前后缀不包含的子串一定是字符串s的最小重复子串。 证明 如果s 是有是有最小重复子串p组成。 即 s n * p 那么相同前后缀可以是这样 也可以是这样 最长的相等前后缀也就是这样 如果字符串s 是有是有最小重复子串p组成最长相等前后缀就不能更长一些 例如这样 如果这样的话因为前后缀要相同所以 p2 p1p3 p2如图 p2 p1p3 p2 即 p1 p2 p3 说明 p p1 * 3。 这样p 就不是最小重复子串了不符合我们定义的条件。 所以如果这个字符串s是由重复子串组成那么最长相等前后缀不包含的子串是字符串s的最小重复子串。 必要性证明 以上是充分性证明以下是必要性证明 如果 最长相等前后缀不包含的子串是字符串s的最小重复子串 那么字符串s一定由重复子串组成吗 最长相等前后缀不包含的子串已经是字符串s的最小重复子串那么字符串s一定由重复子串组成这个不需要证明了。 关键是要要证明最长相等前后缀不包含的子串什么时候才是字符串s的最小重复子串呢。 情况一 最长相等前后缀不包含的子串的长度 比 字符串s的一半的长度还大那一定不是字符串s的重复子串 情况二最长相等前后缀不包含的子串的长度 可以被 字符串s的长度整除如图 步骤一因为 这是相等的前缀和后缀t[0] 与 k[0]相同 t[1] 与 k[1]相同所以 s[0] 一定和 s[2]相同s[1] 一定和 s[3]相同即s[0]s[1]与s[2]s[3]相同 。 步骤二 因为在同一个字符串位置所以 t[2] 与 k[0]相同t[3] 与 k[1]相同。 步骤三 因为 这是相等的前缀和后缀t[2] 与 k[2]相同 t[3]与k[3] 相同所以s[2]一定和s[4]相同s[3]一定和s[5]相同即s[2]s[3] 与 s[4]s[5]相同。 步骤四循环往复。 所以字符串ss[0]s[1]与s[2]s[3]相同 s[2]s[3] 与 s[4]s[5]相同s[4]s[5] 与 s[6]s[7] 相同。 可以推出在由重复子串组成的字符串中最长相等前后缀不包含的子串就是最小重复子串。 即 s[0]s[1] 是最小重复子串 以上推导中你怎么知道 s[0] 和 s[1] 就不相同呢 s[0] 为什么就不能使最小重复子串。 如果 s[0] 和 s[1] 也相同同时 s[0]s[1]与s[2]s[3]相同s[2]s[3] 与 s[4]s[5]相同s[4]s[5] 与 s[6]s[7] 相同那么这个字符串就是有一个字符构成的字符串。 那么它的最长相同前后缀就不是上图中的前后缀而是这样的的前后缀 情况三最长相等前后缀不包含的子串的长度 不被 字符串s的长度整除得情况如图 步骤一因为 这是相等的前缀和后缀t[0] 与 k[0]相同 t[1] 与 k[1]相同t[2] 与 k[2]相同。 所以 s[0] 与 s[3]相同s[1] 与 s[4]相同s[2] 与s[5]即s[0]s[1]与s[2]s[3]相同 。 步骤二 因为在同一个字符串位置所以 t[3] 与 k[0]相同t[4] 与 k[1]相同。 步骤三 因为 这是相等的前缀和后缀t[3] 与 k[3]相同 t[4]与k[5] 相同所以s[3]一定和s[6]相同s[4]一定和s[7]相同即s[3]s[4] 与 s[6]s[7]相同。 以上推导可以得出 s[0],s[1],s[2] 与 s[3],s[4],s[5] 相同s[3]s[4] 与 s[6]s[7]相同。 那么 最长相等前后缀不包含的子串的长度 不被 字符串s的长度整除 就不是s的重复子串 充分条件如果字符串s是由重复子串组成那么 最长相等前后缀不包含的子串 一定是 s的最小重复子串。 必要条件如果字符串s的最长相等前后缀不包含的子串 是 s最小重复子串那么 s是由重复子串组成。 在必要条件这个是 显而易见的都已经假设 最长相等前后缀不包含的子串 是 s的最小重复子串了那s必然是重复子串。 关键是需要证明 字符串s的最长相等前后缀不包含的子串 什么时候才是 s最小重复子串。 同上我们证明了当 最长相等前后缀不包含的子串的长度 可以被 字符串s的长度整除那么不包含的子串 就是s的最小重复子串。 class Solution { public boolean repeatedSubstringPattern(String s) { if (s.equals(“”)) return false; int len s.length();// 原串加个空格(哨兵)使下标从1开始这样j从0开始也不用初始化了s s;char[] chars s.toCharArray();int[] next new int[len 1];// 构造 next 数组过程j从0开始(空格)i从2开始for (int i 2, j 0; i len; i) {// 匹配不成功j回到前一位置 next 数组所对应的值while (j 0 chars[i] ! chars[j 1]) j next[j];// 匹配成功j往后移if (chars[i] chars[j 1]) j;// 更新 next 数组的值next[i] j;}// 最后判断是否是重复的子字符串这里 next[len] 即代表next数组末尾的值if (next[len] 0 len % (len - next[len]) 0) {return true;}return false; }}
http://www.w-s-a.com/news/77240/

相关文章:

  • 淄博网站制作企业高端长沙企业网站制作服务报价
  • 网站服务理念中外商贸网站建设
  • 如何自己建立网站中国建设银行网站忘记密码
  • 什么是a站如何在12366网站上做实名认证
  • 斗蟋蟀网站建设谭谭心怎么建设网站
  • 优秀网站开发商郑州网站建设套餐
  • 做伤残鉴约号网站购物网站建设新闻
  • 黄江网站建设公司自己房子做民宿挂什么网站
  • 手游网站做cpc还是cpm广告号宣武郑州阳网站建设
  • vs连接数据库做网站建立网站
  • 电商网站设计图片素材p2p网站建设石家庄
  • 莲塘网站建设如何文字推广一个婚恋网站
  • 医院网站建设工作汇报WordPress不发邮件了
  • 怎么做外语网站个人网页设计作品ps
  • 网站原型怎么做vps如何建两个网站
  • 商城网站建设源码嘉兴seo计费管理
  • 城乡建设网站证件查询系统wordpress 时间代码
  • php网站建设 关键技术做网站哪家正规
  • 网站开发用什么写得比较好谷歌的英文网站
  • 青岛网站建设公司在哪vivo手机商城
  • 兼职刷客在哪个网站做哪个网站做淘宝客
  • 眼科医院网站开发网络营销特点是什么
  • 提交网站给百度增加wordpress插件
  • 网站建设企业官网体验版是什么Wordpress哪个模板最快
  • 美丽说网站模板湖北可以做网站方案的公司
  • 北京西站进站最新规定建设网站的提成是多少
  • wordpress站点如何加速网站建设描述怎么写
  • 如何免费建造网站免费vi模板网站
  • 商丘做网站多少钱扬州大发网站建设
  • 网站建设哪家性价比高自己做项目的网站