LeetCode题解(0420):强密码检验器(Python)

题目:原题链接(困难)

标签:字符串、贪心算法

解法时间复杂度空间复杂度执行用时
Ans 1 (Python) O ( N ) O(N) O(N) O ( N ) O(N) O(N)36ms (70.73%)
Ans 2 (Python)
Ans 3 (Python)

解法一:

class Solution:
    def strongPasswordChecker(self, password: str) -> int:
        # 处理密码为空的情况
        if not password:
            return 6

        size = len(password)

        # 统计密码中是否存在小写、大写和数字
        lower = any(ch.islower() for ch in password)
        upper = any(ch.isupper() for ch in password)
        number = any(ch.isnumeric() for ch in password)

        # 计算缺失字符的最小修改数量(补齐小写、大写和数字)
        need1 = 3 - (lower + upper + number)

        # 统计所有连续超过3个的字符的位置
        continuities = {}
        i = 0
        while i < size:
            now = 1
            while i + 1 < size and password[i] == password[i + 1]:
                now += 1
                i += 1
            if now >= 3:
                continuities[i] = now
            i += 1

        # 处理密码长度小于6的情况
        if size < 6:
            return max(6 - size, need1)

        # 处理密码长度大于等于6且小于等于20的情况
        elif size <= 20:
            need2 = sum(n // 3 for n in continuities.values())  # 计算处理连续字符的最小修改数
            return max(need1, need2)

        # 处理密码长度大于20的情况
        else:
            m0, m1, m2 = {}, {}, {}
            ans = need1
            for i in continuities:
                if continuities[i] % 3 == 2:
                    m2[i] = continuities[i]
                elif continuities[i] % 3 == 1:
                    m1[i] = continuities[i]
                else:
                    m0[i] = continuities[i]

            for i in m2:  # 先转换 %3==2的
                while m2[i] >= 3 and need1 > 0:  # 转换一次减少3个连续值
                    need1 -= 1
                    m2[i] -= 3
                if need1 == 0:
                    break
            for i in m1:  # 再转换 %3==1的
                while m1[i] >= 3 and need1 > 0:
                    need1 -= 1
                    m1[i] -= 3
                if need1 == 0:
                    break
            for i in m0:  # 最后转换 %3==0的
                while m0[i] >= 3 and need1 > 0:
                    need1 -= 1
                    m0[i] -= 3
                if need1 == 0:
                    break
            if need1 > 0:  # 转换完后x仍然大于0,说明连续的用光了,随便找一数转换为缺失数种类,再删掉多余的数即可,
                return ans + (size - 20)

            # 缺失值补充完后仍有连续值,则先删 m0,再删m1,最后删m2
            while m0 or m1 or m2:
                k0 = list(m0.keys())
                for i in k0:
                    a = m0.pop(i)  # 删掉i
                    if a >= 3:
                        size -= 1
                        ans += 1
                        m2[i] = a - 1  # 余数变为2
                    if size == 20:
                        break

                if size > 20:  # n>20说明删m0不够
                    k1 = list(m1.keys())
                    for i in k1:  # 再删m1
                        a = m1.pop(i)
                        if a >= 3:
                            size -= 2
                            ans += 2
                            m2[i] = a - 2  # 每次删2个,余数变为2
                        if size == 20:
                            break
                        if size == 19:  # 剩19个说明多删了,只需要删1个,省下连续的后面再处理
                            size += 1
                            ans -= 1
                            m0[i] = a - 1  # 删2个变为删1个
                            m2.pop(i)  # 删去刚刚增加的m2的值
                            break

                if size > 20:  # 删m1没结束
                    k2 = list(m2.keys())
                    for i in k2:  # 最后删m2
                        a = m2.pop(i)
                        if a >= 3:
                            size -= 3
                            ans += 3
                            m2[i] = a - 3
                        if size == 20:
                            break
                        elif size == 19:  # 假如剩下22个,删3个变为删2个
                            size += 1
                            ans -= 1
                            m0[i] = a - 2
                            m2.pop(i)
                            break
                        elif size == 18:  # 剩下21个,删3个变为删1个
                            size += 2
                            ans -= 2
                            m1[i] = a - 1
                            m2.pop(i)
                            break
                if size <= 20:  # 删除到固定长度
                    break

            if size > 20:  # 连续的用完了,删去多余的值即可
                return ans + size - 20
            for i in m2:  # 还有连续的,则检查连续值,依次替换得结果
                ans += m2[i] // 3
            for i in m1:
                ans += m1[i] // 3
            for i in m0:
                ans += m0[i] // 3
            return ans
已标记关键词 清除标记
课程简介: 历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring Boot、Spring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务的上线部署运行等流程,如下图所示:
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页