题目描述
如果一个密码满足下述所有条件,则认为这个密码是强密码:
- 由至少 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)