news 2026/4/27 11:26:20

LeetCode 467 环绕字符串中唯一的子字符串

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 467 环绕字符串中唯一的子字符串


文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 核心逻辑拆解
        • 什么叫“连续环绕”?
        • `currentLen` 在干嘛?
        • 为什么 `dp[index] = max(dp[index], currentLen)`?
    • 示例测试及结果
      • 示例 1
      • 示例 2
      • 示例 3
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

这道题第一眼看很容易被“子字符串”“不同”“无限环绕字符串”这些词劝退,但实际上它是一个典型的“计数型动态规划”问题

真正的难点不在字符串本身,而在于:

  • 怎么避免重复统计
  • 怎么在O(n)的复杂度里算清楚所有可能的子串数量

如果你平时做过日志切片、连续事件统计、或者字符串规则分析,这道题的解法思路会非常熟悉。

描述

题目先定义了一个“看起来很吓人”的字符串base

"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd..."

它的特点其实只有一个:

  • 字母是连续递增的
  • 'z'后面可以接'a'

然后问题来了:

给你一个字符串s,统计s中有多少个不同的非空子串
同时也能在base中出现。

注意几个关键信息:

  1. 子串是连续的
  2. 要求不同(不能重复算)
  3. 子串本身必须满足字母连续 + 可 z→a

题解答案

这道题如果暴力枚举子串:

  • 子串数量是 O(n²)
  • 再去判定是否在base中,直接爆炸

真正高效的解法只有一句话:

记录每个字母作为结尾时,最多能形成多长的“连续环绕子串”

核心思想是:

  • 只关心“以某个字符结尾”的最长合法子串
  • 同一个结尾字符,短的子串一定包含在长的里面
  • 所以只统计“最长的那一条”就够了

题解代码分析

下面是完整 Swift 实现,可以直接复制运行。

classSolution{funcfindSubstringInWraproundString(_s:String)->Int{letchars=Array(s)ifchars.isEmpty{return0}// dp[i] 表示:以字符 ('a' + i) 结尾的最长连续子串长度vardp=[Int](repeating:0,count:26)varcurrentLen=0foriin0..<chars.count{ifi>0&&isContinuous(chars[i-1],chars[i]){currentLen+=1}else{currentLen=1}letindex=Int(chars[i].asciiValue!-Character("a").asciiValue!)dp[index]=max(dp[index],currentLen)}returndp.reduce(0,+)}privatefuncisContinuous(_a:Character,_b:Character)->Bool{letaVal=a.asciiValue!letbVal=b.asciiValue!returnbVal==aVal+1||(a=="z"&&b=="a")}}

核心逻辑拆解

什么叫“连续环绕”?

合法情况只有两种:

  • 'a' -> 'b' -> 'c'
  • 'z' -> 'a'
bVal==aVal+1||(a=="z"&&b=="a")

这就是base的全部规则,没有其他花样。

currentLen在干嘛?

currentLen表示:

当前这个字符,能接在前一个字符后面,形成多长的合法子串

比如:

s = "zab"

扫描过程是:

  • 'z'→ currentLen = 1
  • 'a'→ 连续 → currentLen = 2
  • 'b'→ 连续 → currentLen = 3
为什么dp[index] = max(dp[index], currentLen)

这是整道题最关键的一步。

'b'结尾:

  • "b"是合法
  • "ab"是合法
  • "zab"也是合法

但如果你已经有了长度为 3 的"zab"

  • 长度为 1、2 的子串一定已经包含在里面
  • 再统计就会重复

所以我们只保留最长的那个

示例测试及结果

示例 1

letsolution=Solution()print(solution.findSubstringInWraproundString("a"))

分析:

  • 只有一个子串"a"
  • 合法

输出:

1

示例 2

print(solution.findSubstringInWraproundString("cac"))

分析:

  • "c"合法
  • "a"合法
  • "ca"不合法(不是连续)
  • "ac"不合法

输出:

2

示例 3

print(solution.findSubstringInWraproundString("zab"))

分析:

  • "z","a","b"
  • "za","ab"
  • "zab"

一共 6 个。

输出:

6

时间复杂度

整个算法只做了一次线性扫描:

O(n)

n是字符串s的长度,最大 10⁵,完全没压力。

空间复杂度

只用了一个固定长度的数组:

dp[26]

空间复杂度:

O(1)

总结

《环绕字符串中唯一的子字符串》是一道非常典型的“看起来复杂,其实规律极强”的题

它真正想考你的不是字符串 API,而是:

  • 能不能把“不同子串”这个问题压缩成状态统计
  • 能不能意识到:
    同一个结尾字符,只需要记最长那条
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/27 5:37:51

JiaJiaOCR:面向Java ocr的开源库

在 OCR 技术落地过程中&#xff0c;Java 开发者常面临 "Python 生态繁荣&#xff0c;Java 集成困难" 的困境 —— 要么依赖jni调用 exe/dll 外部文件&#xff0c;要么跨平台部署踩坑不断。 JiaJiaOCR 为您带来革命性突破&#xff01; &#x1f389; 本项目将同步更…

作者头像 李华
网站建设 2026/4/22 21:11:03

国企、民企、外企的AI数据治理,为何不能用同一把钥匙?

不同类型企业的数据状况迥异&#xff0c;面临的治理挑战也截然不同&#xff0c;导致通用型方案往往“水土不服”。数据治理&#xff0c;特别是AI赋能的治理&#xff0c;绝非纯粹的技术部署&#xff0c;而是与企业性质、监管环境和发展阶段深度结合的方案。上一期&#xff0c;给…

作者头像 李华
网站建设 2026/4/21 15:28:44

基于yolov11实现车辆速度估计+距离测量+轨迹跟踪+区域进出统计python源码实现

这个是网上目前可能唯一一个使用不足一百行代码实现了复杂车辆速度估计距离测量轨迹跟踪区域进出统计系统。之所以这么简单是因为ultralytics模块现在已经成熟而且强大&#xff0c;不需要从头开始写车辆速度估计、距离测量、轨迹跟踪、区域进出统计系统代码&#xff0c;因为里面…

作者头像 李华
网站建设 2026/4/21 12:51:18

超级逃顶【顶底先知优化、源码、副图、说明】

{}VAR2:LLV(LOW,10); VAR3:HHV(HIGH,25); 阶段卖出: 3.2,COLORCYAN; 3.5,COLOR0088FF; 清仓卖出: 3.5; 动力线: EMA((CLOSE-VAR2)/(VAR3-VAR2)*4,4); STICKLINE(动力线>REF(动力线,1) ,动力线 ,REF(动力线,1),8 ,1),COLORRED; STICKLINE(动力线<REF(动力线,1) ,动力线 ,R…

作者头像 李华
网站建设 2026/4/20 15:42:03

springboot+vue开发实现新能源汽车4s店销售管理系统应用和研究

文章目录摘要项目简介大数据系统开发流程主要运用技术介绍爬虫核心代码展示结论源码文档获取定制开发/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 随着新能源汽车市场的快速发展&#xff0c;传统4S店销售管理模式面临信息化、智能化转型需求…

作者头像 李华