LeetCode刷题日记2022-4-2/420. 强密码检验器-分类讨论

420. 强密码检验器

题目描述

如果一个密码满足下述所有条件,则认为这个密码是强密码:

  • 由至少 6 个,至多 20 个字符组成。
  • 至少包含 一个小写 字母,一个大写 字母,和 一个数字 。
  • 同一字符 不能 连续出现三次 (比如 “…aaa…” 是不允许的, 但是 “…aa…a…” 如果满足其他条件也可以算是强密码)。
  • 给你一个字符串 password ,返回 将 password 修改到满足强密码条件需要的最少修改步数。如果 password 已经是强密码,则返回 0 。

在一步修改操作中,你可以:

  • 插入一个字符到 password ,
  • 从 password 中删除一个字符,或
  • 用另一个字符来替换 password 中的某个字符。

示例 1:

输入:password = "a"
输出:5

示例 2:

输入:password = "aA1"
输出:3

示例 3:

输入:password = "1337C0d3"
输出:0

提示:

  • 1 <= password.length <= 50
  • password 由字母、数字、点 ‘.’ 或者感叹号 ‘!’

题解思路

我们分为三种情况来进行讨论:

情况一: 当密码的长度小于6的时候,即密码长度不合法且种类是否重复都不一定合法的时候

  • 这个时候我们需要对密码进行添加操作 操作的次数为n-6个 同时还要判断密码是否都包括了3种类型
    • 针对存在重复的我们只需要向其中添加不同字母 保证其不连续即可
  • 也就是说我们要在(n-6)和(3-种类)找到最大值并返回

情况二: 当密码的长度大于等于6 且小于等于20的时候 也就是密码长度合法但种类跟重复数字不一定合法

  • 我们首先找到字符串中3个连续出现重复字母的有多少组 然后每组需要消耗一次替换操作

情况三: 当密码的长度大于20的时候 也就是密码长度不合法且种类跟重复不一定合法

重复情况

  • n%3==0,我们进行一次删除操作的时候即相当于对其进行一次替换操作
  • n%3==1,我们对其删除2个字符相当于进行一次替换操作
  • n%3==2,我们对其进行删除3个字符相当于进行一次替换操作

  • 我们在删除的时候就删除重复的字符 这就相当于直接对字符串进行替换操作
  • 我们先对 n%3==0 的情况进行删除
  • 同时记录下 n%3==1 有多少组
  • 最后先对n%3==1遍历有多少组
  • 然后在遍历 n%3==2有多少组 进行删除跟替换操作

题解代码

class Solution:
    def strongPasswordChecker(self, password: str) -> int:
        n=len(password)
        has_low,has_upper,has_digit=False,False,False
        for ch in password:
            if ch.islower():
                has_low=True
            elif ch.isupper():
                has_upper=True
            elif ch.isdigit():
                has_digit=True
        
        categories=has_digit+has_low+has_upper

        if n<6:
            return max(6-n,3-categories)
        elif n<=20:
            replace=cnt=0

            cur='#'
            for ch in password:
                if ch==cur:
                    cnt+=1
                else:
                    replace+=cnt//3
                    cnt=1
                    cur=ch
            replace+=cnt//3
            return max(replace,3-categories)
        else:
            replace,remove=0,n-20
            cnt=remove2=0

            cur='#'
            for ch in password:
                if ch==cur:
                    cnt+=1
                else:
                    if remove>0 and cnt>=3:
                        if cnt%3==0:
                            replace-=1
                            remove-=1
                        elif cnt%3==1:
                            remove2+=1
                    replace+=cnt//3
                    cnt=1
                    cur=ch
            if remove>0 and cnt>=3:
                if cnt%3==0:
                    remove-=1
                    replace-=1
                elif cnt%3==1:
                    remove2+=1

            replace+=cnt//3

            use2=min(replace,remove2,remove//2)
            replace-=use2
            remove-=use2*2
            use3=min(replace,remove//3)
            replace-=use3
            remove-=use3*3
            return (n-20)+max(replace,3-categories)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值