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

LeetCode 420 - 强密码检验器

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 代码详细解析
        • ① 检查字符类型
        • ② 查找连续重复段
        • ③ 根据长度情况分支
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

这道题是 LeetCode 第 420 题:强密码检验器(Strong Password Checker)
乍一看挺简单:“判断一个密码是否够强”,但实际上这题的规则相当复杂。要同时考虑 长度、字符种类、重复字符、替换、插入和删除操作

这题在算法上属于一个典型的 字符串修复 + 贪心策略 + 分类讨论 问题,难度在 LeetCode 上是 Hard
本篇我们会用 Swift 来实现一个清晰、可运行的版本,并讲透整个逻辑。

描述

题意总结一下:

给定一个字符串 password,我们要让它变成“强密码”。所谓强密码,要满足三个条件:

  1. 长度要求
    必须在 [6, 20] 之间。
  2. 字符种类要求
    至少要有一个小写字母、一个大写字母、一个数字。
  3. 连续字符要求
    不允许出现连续三个一样的字符。

可以通过三种操作实现修改:

  • 插入一个字符
  • 删除一个字符
  • 替换一个字符

我们要找出 最少的修改次数

举几个例子:

  • "a" → 长度太短、缺大写、缺数字,至少要补5步。
  • "aA1" → 长度刚好够,但太短,得补3步。
  • "1337C0d3" → 本身已经完美,0步!

题解答案

这道题的核心在于分情况处理:

  1. 如果长度 < 6
    主要靠插入字符补足长度,同时考虑字符种类不全的情况。

  2. 如果长度 > 20
    主要靠删除字符缩短长度,但删除时要尽量减少三连字符的数量。

  3. 长度在 [6, 20] 内
    不用插入或删除,只要通过替换字符来打破重复或补充缺少的字符类型。

所以整体上,我们要关注三个指标:

  • missingTypes:缺少的字符类型数量(如没大写、没数字)
  • replace:为打断三连字符而需要替换的次数
  • deleteCount:当超长时需要删除的次数

最终的答案根据不同情况计算。

题解代码分析

下面是 Swift 实现的完整代码(可直接在 Xcode Playground 运行)

import Foundationclass Solution {func strongPasswordChecker(_ password: String) -> Int {let chars = Array(password)var hasLower = false, hasUpper = false, hasDigit = false// 检查字符类型for c in chars {if c.isLowercase { hasLower = true }else if c.isUppercase { hasUpper = true }else if c.isNumber { hasDigit = true }}let missingTypes = [hasLower, hasUpper, hasDigit].filter { !$0 }.countvar repeats = [Int]()var i = 0// 找出连续重复字符段长度while i < chars.count {var j = iwhile j < chars.count && chars[j] == chars[i] { j += 1 }if j - i >= 3 { repeats.append(j - i) }i = j}let n = chars.count// 太短:主要补长度和类型if n < 6 {return max(6 - n, missingTypes)}// 太长:先删除if n > 20 {var deleteCount = n - 20var toDelete = deleteCount// 优先削减重复段,按 (len % 3) 的顺序删for k in 0..<3 {for idx in 0..<repeats.count {if toDelete == 0 { break }if repeats[idx] < 3 || repeats[idx] % 3 != k { continue }let del = min(toDelete, k + 1)repeats[idx] -= deltoDelete -= del}}// 剩余部分还需替换let replace = repeats.reduce(0) { $0 + $1 / 3 }return deleteCount + max(missingTypes, replace)}// 3️⃣ 正常长度:只需替换重复或补类型let replace = repeats.reduce(0) { $0 + $1 / 3 }return max(missingTypes, replace)}
}

代码详细解析

我们把代码逻辑拆开讲

① 检查字符类型
for c in chars {if c.isLowercase { hasLower = true }else if c.isUppercase { hasUpper = true }else if c.isNumber { hasDigit = true }
}

统计是否包含三种类型(小写、大写、数字),后面用于计算 missingTypes

② 查找连续重复段
while i < chars.count {var j = iwhile j < chars.count && chars[j] == chars[i] { j += 1 }if j - i >= 3 { repeats.append(j - i) }i = j
}

例如 "aaaBBBcc" 会得到 [3, 3],表示有两处三连。

③ 根据长度情况分支
  • 短密码(<6)
    直接 max(6 - n, missingTypes)
    举例 "aA1" 长度3,缺0种,结果为 max(6-3,0)=3

  • 长密码(>20)
    优先删除(尽量减少重复段),再替换。
    删除时的贪心顺序是:

    • 先删 len % 3 == 0 的段
    • 再删 len % 3 == 1
    • 最后删 len % 3 == 2
      这样能最大化减少替换次数。
  • 正常长度(6~20)
    不需删除,直接看要替换多少次打断三连,同时要补类型。

示例测试及结果

let solution = Solution()print(solution.strongPasswordChecker("a"))         // 输出: 5
print(solution.strongPasswordChecker("aA1"))       // 输出: 3
print(solution.strongPasswordChecker("1337C0d3"))  // 输出: 0
print(solution.strongPasswordChecker("aaaaa"))     // 输出: 2
print(solution.strongPasswordChecker("Aa123"))     // 输出: 1

输出结果:

5
3
0
2
1

可以看到结果完全符合预期。
特别是 "aaaaa" 这种情况,长度不够还存在连续重复,所以要补 2 步。

时间复杂度

  • 遍历字符和计算重复段都是 O(n)。
  • 删除和替换阶段的处理也是 O(n)。

时间复杂度:O(n)

空间复杂度

我们额外用了一个 repeats 数组来记录连续段长度,
最多存储 n/3 个元素。

空间复杂度:O(n)

总结

这道题虽然是“密码强度检测”,但其实是一个挺复杂的算法题。
它融合了:

  • 贪心策略(先删重复)
  • 分类讨论(长度分段)
  • 模拟操作(插入、删除、替换)

在真实项目中,这种算法思想其实挺实用的,比如:

  • 用户注册系统的密码强度提示
  • 输入规则实时校验(前端 + 后端)
  • 安全策略模拟测试

Swift 在字符串处理上相对安全(Unicode友好),
但因为没有直接的字符下标操作,所以需要注意 Array 转换。

http://www.dtcms.com/a/593162.html

相关文章:

  • 优化学校网站建设方案下载官方网站app
  • Visual Basic 创建状态栏
  • 网站建设的人才怎么称呼wordpress多语言模板
  • LeetCode 分类刷题:876. 链表的中间结点
  • LeetCode 分类刷题:143. 重排链表
  • 分布式专题——51 ES 深度分页问题及其解决方案详解
  • 2025.11.10 力扣每日一题
  • 麻城网站开发同一网站相同form id
  • dede网站制作wordpress长微博工具
  • 专业定制铸铁T型槽地轨,提供稳定的制造、实验基准线
  • PyCharm如何像其他idea软件跨行选择文本
  • 【场景题】线上接口响应慢,应该如何排查问题?
  • Product Hunt 每日热榜 | 2025-11-10
  • 【智能体(Agent)技术深度解析】从架构到实现细节,核心是实现“感知环境→处理信息→决策行动→影响环境”的闭环
  • 网站的登陆注册页面怎么做做水果网站弄个什么名字
  • Advisor与@Aspect
  • Java基础——集合进阶6
  • 网站建设湛江分类信息网站如何做排名
  • 二十七、通信接口
  • 个人网站备案条件个人怎么做网页
  • SQL 相关子查询:性能杀手及其优化方法
  • 一文掌握UI自动化测试
  • 金融保险银行营销AI数字化转型培训讲师培训老师唐兴通讲金融银保团队险年金险市场销售
  • 质效飞跃,优测金融数智质效解决方案全新升级!
  • 智网案例精选|光联云网融合智驱,重塑金融数字化转型新格局
  • 自适应网站建设极速建站WordPress更新emoji
  • watch监视-ref对象类型数据
  • 网站建设的英语怎么做淘宝客网站做淘客
  • MBSE:数字模型重塑系统工程未来
  • 排序算法的相关讨论