IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【leetCode】强密码检验器 -> 正文阅读

[数据结构与算法]【leetCode】强密码检验器

问题描述
在这里插入图片描述
思路:
按照原字符串的顺序用字典法创建字典,键值为连着的该元素的个数。
1、首先检测是否有需要添加的数据类型和是否有需要增加或减去字符。
创建完字典后先判断是否有三个以上连续的值,有要通过插入元素来分离,3个需要1个,4个需要一个,5个需要两个,6个需要两个,7个需要3个,方法为n/2-1+n%2
如果是更换元素 3-1 4-1 5-1 6-2 7-2 那他需要的次数为n/3

对于这道题来说删除、插入、替换的顺序很重要。
先说说题解的方法。
大问题分小问题,
根据字符的长度可以分为三种:1、长度小于6的时候。2、长度小于等于20大于等于6的时候3、长度大于20的时候
第一种可能性长度小于6的时候:他只有两种更改方法:第一种是替换,第二种是插入,且连续字符长度为5,替换更改连续字符的方法最多只需要替换一次。
所以它的结果只需要考虑插入元素补长度和替换种类里的大者就可以。
**第二种可能性,**没有删除没有插入,只有替换。
直接替换步数就等于处理连续字替换数和缺失类型替换数取大者
第三种可能性,是最繁琐的因为它混入了删除,所以他需要考虑替换的连续组的连续数 %32 -> 连续数%31 -> 连续数%30,然后处理多余字符,删除的优先级是连续组的连续数 %30 -> 连续数%31 -> 连续数%32。这个删除的次数,不能一次用完,因为如果余数为0,他就只需要删除一次就可以减少一次替换数。而余数为1,它就需要减少两次减少一次替换数。
这是题解的代码理解一下。

class Solution:
    def strongPasswordChecker(self, password: str) -> int:
        n = len(password)       #密码长度
        has_lower = has_upper = has_digit = False       #用于看看3种情况是否都有
        for ch in password:     #用各种判断函数来判断是否有这几种符号
            if ch.islower():
                has_lower = True
            elif ch.isupper():
                has_upper = True
            elif ch.isdigit():
                has_digit = True


        categories = has_lower + has_upper + has_digit     #种类


        if n < 6:       #如果字符串长度小于6,就是要增加字符个数,和要添加种类的大者
            return max(6 - n, 3 - categories)
        elif n <= 20:   #长度在6-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
            # k mod 3 = 1 的组数,即删除 2 个字符可以减少 1 次替换操作
            rm2 = cnt = 0
            cur = "#"   #当前字符


            for ch in password:
                if ch == cur:
                    cnt += 1    #当前字符连续次数
                else:
                    if remove > 0 and cnt >= 3:
                        if cnt % 3 == 0:
                            # 如果是 k % 3 = 0 的组,那么优先删除 1 个字符,减少 1 次替换操作
                            remove -= 1
                            replace -= 1
                        elif cnt % 3 == 1:
                            # 如果是 k % 3 = 1 的组,那么存下来备用
                            rm2 += 1    #记录余数为1的数组
                        # k % 3 = 2 的组无需显式考虑
                    replace += cnt // 3 #所有的重复数都用替换处理,上面是提前减1,所以他这里余数为1的情况是不用dlt处理的
                    cnt = 1
                    cur = ch


            if remove > 0 and cnt >= 3: #用于处理当连续字符在最后的时候
                if cnt % 3 == 0:
                    remove -= 1
                    replace -= 1
                elif cnt % 3 == 1:
                    rm2 += 1


            replace += cnt // 3


            # 使用 k % 3 = 1 的组的数量,由剩余的替换次数、组数和剩余的删除次数共同决定
            use2 = min(replace, rm2, remove // 2)
            replace -= use2
            remove -= use2 * 2
            # 由于每有一次替换次数就一定有 3 个连续相同的字符(k / 3 决定),因此这里可以直接计算出使用 k % 3 = 2 的组的数量
            use3 = min(replace, remove // 3)
            replace -= use3
            remove -= use3 * 3
            return (n - 20) + max(replace, 3 - categories)
strs = "aaaaAAAAAA000000123456"
a = Solution().strongPasswordChecker(strs)
print(a)

而我的代码!很繁琐,但是是我的想法。
有兴趣的可以理解 很垃圾- -

class Solution:
    def strongPasswordChecker(self, password: str) -> int:
        insert = 0      #记录需要插入的次数
        dlt = 0         #记录需要删除的次数
        alter = 0       #记录需要改变的次数,这里是种类
        mod_dlt = 0     #结果中需要删除的次数
        mod_alter = 0   #结果中需要改变的次数,种类
        mod_insert=0    #结果中需要插入的次数
        modify = 0      #结果中需要用修改来解决连续字符的次数
        length = len(password)
        flag = [False,False,False]  #用来判断三种字符是否都有
        if length<6:
            insert = 6-length
        elif length>20:
            dlt = length - 20
        for i in range(0,length):
            if password[i]>='a' and password[i]<='z':
                if flag[0] == False:
                    flag[0] = True
            elif password[i] >= 'A' and password[i] <= 'Z':
                if flag[1] == False:
                    flag[1] = True
            elif password[i]>='0' and password[i]<='9':
                if flag[2] == False:
                    flag[2] = True
            if flag == [True,True,True]:
                break
        alter = flag.count(False)
        if alter >0 and  insert >alter:
            insert -= alter
        elif alter >0 and insert>0:
            alter -=insert
        rm2 = 0
        cur = 0
        for i in range(0,length):
            if i==0:
                cur=1
            elif password[i] == password[i-1]:
                cur+=1
            elif password[i]!=password[i-1]:
                if cur >= 3:
                    if dlt>0 and cur%3==0:
                        mod_dlt+=1
                        dlt-=1
                        cur -=1
                    elif dlt>0 and cur%3==1:
                        rm2+=1


                    if cur>=3:
                        if insert>0:
                            t = int(cur/2-1+cur%2)
                            if t<=insert:
                                insert -=t
                                mod_insert += t
                                cur -= t*2
                            else:
                                cur -= insert * 2
                                mod_insert += insert
                                insert = 0
                        if cur>=3:
                            if alter>0:
                                t = int(cur/3)
                                if t <= alter:
                                    cur -= t * 3
                                    mod_alter += t
                                    alter -=t
                                else:
                                    mod_alter += alter
                                    cur = cur - alter * 3
                                    alter =0


                modify+=int(cur/3)
                cur =1
        if cur >= 3:
            if dlt > 0 and cur % 3 == 0:
                mod_dlt += 1
                dlt -= 1
                cur -= 1
            elif dlt > 0 and cur % 3 == 1:
                rm2 += 1
            if cur >= 3:
                if insert > 0:
                    t = int(cur / 2 - 1 + cur % 2)
                    if t <= insert:
                        insert -= t
                        mod_insert += t
                        cur -= t * 2
                    else:
                        cur -= insert * 2
                        mod_insert += insert
                        insert = 0
                if cur >= 3:
                    if alter > 0:
                        t = int(cur / 3)
                        if t <= alter:
                            cur -= t * 3
                            mod_alter += t
                            alter -= t
                        else:
                            mod_alter += alter
                            cur = cur - alter * 3
                            alter = 0


        modify += int(cur / 3)
        cur = 1
        use2 = min(modify, rm2, dlt // 2)
        modify -= use2
        mod_dlt+=use2*2
        dlt -= use2*2
        use3 = min(modify,  dlt // 3)
        modify -= use3
        mod_dlt+=use3*3
        dlt -= use3*3
        return int(modify+mod_alter+mod_dlt+mod_insert+dlt+insert+alter)


strs = "aaaabbbbccccddeeddeeddeedd"
a = Solution().strongPasswordChecker(strs)
print(a)
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:36:03  更:2022-04-04 12:37:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:43:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码