leetcode 420. 强密码检验器 ( hard 模拟)

请添加图片描述

请添加图片描述

class Solution:
    def strongPasswordChecker(self, password: str) -> int:
        n = len(password)

        if n < 3:
            return 6 - n
        
        flag1 = False # 是否出现了小写字母
        flag2 = False # 是否出现了大写字母
        flag3 = False # 是否出现了数字

        list0 = [str(j) for j in range(10)]
        list1 = ['.', '!'] + list0

        for i in password:

            # 判断是不是数字
            if not flag3:
                if i in list0:
                    flag3 = True
            
            # 判断是不是小写字母
            if not flag1:
                if i in list1:
                    continue
                if i.lower() == i:
                    flag1 = True

            # 判断是不是大写字母
            if not flag2:
                if i in list1:
                    continue
                if i.upper() == i:
                    flag2 = True

            if flag1 and flag2 and flag3:
                break
            
        # 由于重复需要进行调整的步数
        repeat_info = []
        repeat_time = 0
        pre = password[0]
        for i in password:
            if i != pre:
                if repeat_time >= 3:
                    repeat_info.append(repeat_time)
                repeat_time = 1
                pre = i
            else:
                repeat_time += 1
        if repeat_time >= 3:
            repeat_info.append(repeat_time)
        adjust_count = 0
        for i in repeat_info:
            adjust_count += i // 3
        
        # 由于flag1-3需要进行调整的步数
        adjust_count2 = 0
        if not flag1:
            adjust_count2 += 1
        if not flag2:
            adjust_count2 += 1
        if not flag3:
            adjust_count2 += 1


        # 如果password长度小于6,还需要进行补
        if n < 6:
            return max(6 - n, adjust_count, adjust_count2)

        # 如果password长度已经大于6,不需要补,只需要满足flag1-3和不重复3次以上
        elif n <= 20:
            return max(adjust_count2, adjust_count)

        # 如果password长度大于20,还需要进行删除
        else:
            del_time = n - 20
            # 删除的策略,需要分析repeat_info
            # 比如有a重复了15次,需要修改5次,那么删除一个a就只需要修改4次
            # 如果有a重复了14次,删除一个a并不能改变修改的次数,要删除两个a
            # 因此优先策略是:

            # 优先把3整数倍的重复次数减1
            index = 0
            while del_time >= 1 and index < len(repeat_info):
                if repeat_info[index] % 3 == 0:
                    repeat_info[index] -= 1
                    del_time -= 1
                index += 1
            repeat_info = [i for i in repeat_info if i >= 3]

            # 再优先把3整数倍+1的重复次数减2
            index = 0
            while del_time >= 2 and index < len(repeat_info):
                if repeat_info[index] % 3 == 1 and repeat_info[index] >= 3:
                    repeat_info[index] -= 2
                    del_time -= 2
                index += 1
            repeat_info = [i for i in repeat_info if i >= 3]
            
            # 如果还有del_time剩,就随便减至2
            index = 0
            while del_time > 0  and index < len(repeat_info):
                if repeat_info[index] - 2 <= del_time:
                    del_time -= repeat_info[index] - 2
                    repeat_info[index] = 2
                else:
                    repeat_info[index] -= del_time
                    del_time = 0
                index += 1
            
            # 重新计算因重复而调整的次数
            adjust_count = 0
            for i in repeat_info:
                adjust_count += i // 3

            return n - 20 + max(adjust_count2, adjust_count)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值