问题描述 思路: 按照原字符串的顺序用字典法创建字典,键值为连着的该元素的个数。 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
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:
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
rm2 = cnt = 0
cur = "#"
for ch in password:
if ch == cur:
cnt += 1
else:
if remove > 0 and cnt >= 3:
if cnt % 3 == 0:
remove -= 1
replace -= 1
elif cnt % 3 == 1:
rm2 += 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:
rm2 += 1
replace += cnt // 3
use2 = min(replace, rm2, remove // 2)
replace -= use2
remove -= use2 * 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)
|