密码检验器 II"/>
LeetCode每日一题2299. 强密码检验器 II
Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法......感兴趣就关注我吧!你定不会失望。
🌈个人主页:主页链接
🌈算法专栏:专栏链接 现已更新完KMP算法,之后我会继续往里填充内容哒。
🌈代码仓库:Gitee链接
🌈点击关注=收获更多优质内容🌈
目录
题解:
模拟法:
位运算:
思路:
总结:
完结撒花:
本题是一道LeetCode上的简单题,使用了模拟、位运算两种方法解题,各位看官往下看。
题解:
先来看看题目:
如果一个密码满足以下所有条件,我们称它是一个 强 密码:
- 它有至少
8
个字符。- 至少包含 一个小写英文 字母。
- 至少包含 一个大写英文 字母。
- 至少包含 一个数字 。
- 至少包含 一个特殊字符 。特殊字符为:
"!@#$%^&*()-+"
中的一个。- 它 不 包含
2
个连续相同的字符(比方说"aab"
不符合该条件,但是"aba"
符合该条件)。给你一个字符串
password
,如果它是一个 强 密码,返回true
,否则返回false
。
换成程序语言来看就是:一个字符串里必须要有大小写字母、题给特殊符号、数字,且邻位字符不能相同。
模拟法:
首先来看看比较容易想出来的方法,模拟法:将题目给的条件翻译成代码,较为简单,咱直接上代码。
class Solution {
public:bool strongPasswordCheckerII(string password) {if (password.size() < 8)return false;int lower = 0, upper = 0, digit = 0, star = 0, special = 0;for (int i = 0; i < password.size(); i++){if (i > 0){char ret = password[i - 1];if (ret == password[i])return false;}if (isdigit(password[i]))digit = 1;else if (islower(password[i]))lower = 1;else if (isupper(password[i]))upper = 1;else special = 1;}if (lower && upper && digit && special)return true;else return false;}
};
这种方法的优点:好想,可能看完题目那一瞬间就能想的出来。
但弊端也是显而易见的:代码冗杂、比较生硬的翻译且因为创建了几个变量来统计相应字符出现的概率,所以占用空间也比较大。
这里不过多解释这种代码,下面着重介绍位运算的方法
位运算:
先来了解一个简单的知识:|运算。有两个数,a=8、b=1,将这两个数都以二进制展开为
a=1000,b=0001,这时候a|b就是按照这样一个法则:有1为1其余为0,将他们对齐后是这样,根据我们的法则,最后的结果会是1001
很容易就可以看出|运算可以将一个数展开然后进行计数,相当于每一位都可以是一种情况的出现。这就大大节省了我们需要创建多个变量的空间。
下面进入正题:
一个字符串里必须要有大小写字母、题给特殊符号、数字,且邻位字符不能相同。
分析题干,可以想明白有四种字符要出现,且一种情况不能出现。四种情况:我们设置一个变量改变他的低四位,二进制下的:1111,也就是十进制的:15。表示这四种情况都出现了。
下面上代码
class Solution {
public:bool strongPasswordCheckerII(string password) {if(password.size()<8)return -1;int i=0,mask=0;while(i<password.size()){if(i&&password[i]==password[i-1])return false;if(isdigit(password[i]))mask|=1;else if(islower(password[i]))mask|=2;else if(isupper(password[i]))mask|=4;elsemask|=8;i++;}return mask==15;}};
思路:
若字符串长度小于8,则直接return false;
创建计数变量mask。进入循环。
先判断邻位是否存在是否相同这一情况。注意这里可能会存在越位访问的情况:若i=0时,他的邻位就是-1,访问password[-1]是越位访问,所以为了避免这种情况 我们加入了(i&&password)当i为0时此项判断为假直接退出判断,i!=0时这项为真进入下一层判断邻位是否相等。
接下来进行四种情况的判断,若出现则|运算为相应的值,改变二进制下对应位(数字改变0001 小写字母改变0010 大写字母改变0100 特殊符号改变 1000)
当i=字符串长度时退出循环。
之后判定mask是否等于15(1111 四种情况都出现),若真则返回真,若假返回假。
附上LeetCode的成绩:
总结:
利用|位运算判断是否出现一次的情况,大大减少了多次创建变量空间的占用。
完结撒花:
🌈本篇博客的内容【LeetCode每日一题2299. 强密码检验器 II】已经结束。
🌈本篇代码链接:Gitee
🌈LeetCode:题目链接
🌈若对你有些许帮助,可以点赞、关注、评论支持下博主,你的支持将是我前进路上最大的动力。
🌈若以上内容有任何问题,欢迎在评论区指出。若对以上内容有任何不解,都可私信评论询🌈问。
🌈诸君,山顶见!
更多推荐
LeetCode每日一题2299. 强密码检验器 II
发布评论