博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
420. Strong Password Checker
阅读量:4613 次
发布时间:2019-06-09

本文共 4629 字,大约阅读时间需要 15 分钟。

不定期更新leetcode解题java答案。

采用pick one的方式选择题目。

  本题为密码检测程序,给定字符串,要求1、字符串长度在6~20之间,2、字符串至少包含小写字母、大写字母和数字,3、字符串不允许存在3个连续的相同字符。(如:"aaa")

  问:需要几次变换操作可以将给定字符串改写为规范密码字符串。变换操作包括:1、插入一个字符,2、删除一个字符,3、修改一个字符。

  首先考虑长度问题,如果小于6个或者大于20个字符,每多一个字符必须做出一次处理,如果少则插入;多则删除。

  然后考虑字符类型问题,每少一种字符类型则需要插入或者修改处理。

  最后关于连字符串,则可以采用修改、插入、删除,三种方式来进行处理。

  我们分析一下这三种方式对三种要求的影响:

  1、对长度的关系是最直接的,小则加,大则删,N——N;变化不能增加长度。

  2、若字符类型少,采用插入或者修改对其影响相同,N——N;删除不能增加类型。

  3、若存在连续字符,试考虑对一个长度为N的连续字符,删除操作:重复字符长度减1,N——N-1;插入操作:重复字符长度减2,N——N-2;修改操作:重复字符长度-3,N——N-3。

  

  有如上规则可以试想长度若小,则增加的时候尽量增加字符类型,并且由于插入时可以减少存在连续字符的长度,如:"aaaaab",插入后可变为"aaa1aab",由于本题中长度最低限度较小,偷懒没有将插入的分析加入(因为连续字符不满足要求的最小长度是3,这个东西可以看下文以及代码进行理解)。若长度较大,则进行删除操作,此时应尽可能满足删除连续字符长度为3的倍数中的字符,其次为连续字符长度为3的倍数+1中的字符(为了删除操作多时尽可能的减少之后的修改操作,后文会提到),最后是删除连续字符长度为3的倍数+2中的字符。

  此时完成了长度要求,若长度要求满足,种类缺少,我们尽可能采用修改操作,不考虑插入操作。由于插入操作不只变换了长度(影响了第一步),而且插入操作减少连续字符的数量也没有修改操作多:N-2变化的小于N-3。

  最后是对存在的连续字符进行操作,通过上述分析,很明显可以看出使用修改操作最小化操作次数。

  由上可得如下代码:

1 public class Solution { 2     public int strongPasswordChecker(String s) { 3         boolean hasDigit = false, hasLowercase = false, hasUppercase = false; 4          5         char lastChar = ' '; 6         int count = 1; 7         ArrayList
repeatCounts = new ArrayList
(); 8 9 for(int i = 0; i < s.length(); i++){10 char tmpChar = s.charAt(i);11 12 //判断是否存在要求的字符13 if(tmpChar <= '9' && tmpChar >= '0')14 hasDigit = true;15 else if(tmpChar <= 'Z' && tmpChar >= 'A')16 hasUppercase = true;17 else if(tmpChar <= 'z' && tmpChar >= 'a')18 hasLowercase = true;19 20 //统计超过3连字符串的数量以及对应的个数21 if(lastChar == tmpChar){22 count++;23 }else{24 if(count >= 3)25 repeatCounts.add(count);26 27 count = 1;28 }29 lastChar = tmpChar;30 }31 //循环结束后没有处理当前统计长度32 if(count >= 3)33 repeatCounts.add(count);34 35 //记录长度问题36 int lengthDifference = 0;37 if(s.length() > 20)38 lengthDifference = s.length() - 20;39 else40 lengthDifference = s.length() < 6 ? s.length() - 6 : 0;41 42 int steps = Math.abs(lengthDifference);43 44 int types = (hasDigit ? 0 : 1) + (hasUppercase ? 0 : 1) + (hasLowercase ? 0 : 1);45 46 //先满足长度要求47 if(lengthDifference < 0){48 while(lengthDifference != 0){49 lengthDifference++;50 types--;51 //本题中如果长度小,那么插入一个即可消除全部3连的52 repeatCounts.clear(); //这里偷懒了,如果字符串长度要求下限较大则应采用添加的方式进行处理,类同删除操作:条件稍微变化,N-1变为N-253 }54 }else if(lengthDifference > 0){55 while(lengthDifference != 0){56 lengthDifference--;57 if(repeatCounts.size() != 0){58 //删除操作 循环3次用于考虑先减哪种长度的连串59 for(int i = 0; i < repeatCounts.size() * 3; i++){60 int loc = i % repeatCounts.size();61 if(repeatCounts.get(loc) % 3 == 0){62 repeatCounts.set(loc, repeatCounts.get(loc) - 1);63 break;64 }65 if(i >= repeatCounts.size() && repeatCounts.get(loc) % 3 == 1 && repeatCounts.get(loc) > 3){66 repeatCounts.set(loc, repeatCounts.get(loc) - 1);67 break;68 }69 if(i >= repeatCounts.size() * 2 && repeatCounts.get(loc) > 3){70 repeatCounts.set(loc, repeatCounts.get(loc) - 1);71 break;72 }73 }74 }75 }76 }77 78 //长度满足要求考虑种类要求79 while(types > 0){80 if(repeatCounts.size() != 0){81 for(int i = 0; i < repeatCounts.size(); i++){82 if(repeatCounts.get(i) >= 3){83 repeatCounts.set(i, repeatCounts.get(i) - 3);84 break;85 }86 }87 }88 types--;89 steps++;90 }91 92 for(int i = 0; i < repeatCounts.size(); i++){93 steps += repeatCounts.get(i) / 3;94 }95 96 return steps;97 }98 }

 

转载于:https://www.cnblogs.com/zslhq/p/5986623.html

你可能感兴趣的文章
ORM + Mysql配置
查看>>
18 python 初学(time、random 模块)
查看>>
那些年我们扔过的漂流瓶
查看>>
javascript:巧用eval函数组装表单输入项为json对象
查看>>
2.grep、awk、sed、cut处理文本
查看>>
为什么我们叫雪狼队
查看>>
wpf button变成圆角
查看>>
测试开发学习进阶教程 视频&PDF
查看>>
C#基础-连接Access与SQL Server
查看>>
autofac
查看>>
MacOS 系统终端上传文件到 linux 服务器
查看>>
Excel导出POI
查看>>
兼容性
查看>>
自动执行sftp命令的脚本
查看>>
转 Merkle Tree(默克尔树)算法解析
查看>>
网络编程基础之socket编程
查看>>
各种浏览器的user-agent和
查看>>
Restful levels
查看>>
Phonegap移动开发:布局总结(一) 全局
查看>>
Java 变参函数的实现
查看>>