[算法分析与设计] leetcode 每周一题: 420. Strong Password Checker
来源:互联网 发布:办公室网络综合布线 编辑:程序博客网 时间:2024/06/18 18:18
题目链接:
420. Strong Password Checker
题目大意:
给定一个代表密码的字符串 s, 只有当其同时满足以下 3个条件时才能视其为 "强密码":
1. 长度在区间 [6, 20] 内 (按字符计) ;
2. 至少分别包含 大写字母, 小写字母, 数字 各一个 ;
3. 任何连续的三个字符不完全相同 (比如: "..aaa.." 就不行, 而 "..aa.a.." 就可以) ;
现判断 s 是否是一个 "强密码", 若是, 返回 0 ; 若不是, 则返回 将 s 转换为一个 "强密码" 的最小 Levenshtein距离 ;
解题过程:
(1) 题意明显, ... 相对于算法题, 这题更像是业务逻辑处理 ... 包成个数据结构写起来会好看得多 ;
(2) 自然的思路便是 先对 s 做检查, 记录相关信息, 然后据此求出 最小编辑距离 ;
(3) 略麻烦的是 求最小编辑距离 的逻辑部分, 这里注意 插入字符操作 和 替换字符操作 对于 重复字符(条件3) 和 缺失字符(条件2) 来说没有太大区别 (显然这里不用考虑词频问题, 因为总会有 可以通过 被替换 的方式修正 条件2 的缺陷 的字符存在(要么是重复字符, 要么是多次出现的另一类必须字符, 要么是其他的无关字符, 注意长度必须 >= 6)), 此时对 n个连续重复字符 来说, 只需要做n / 3 次处理即可断开其连续重复 ; 而 删除字符 操作 则有所区别, 其只有 2个意义, 对 重复字符 的意义在于 ((3n - 1) / 3) - (3n / 3) = 1, 有效减少人口 ... ; 以及对 控制长度 的意义 ;
(4) 综合来看, 可以发现 不同的处理操作可以有不同的优先级, 这里我先进行 缩减长度的处理, 这时同时考虑不同长度的 连续重复字符 也有优先级 ; 另外还要考虑可复用的操作 ;
代码如下:
( 注: 代码略冗长, 可以进一步简化 .. )
class Solution {public: int strongPasswordChecker(string s) { auto length = s.size(); if (length == 0) { return 6; } map< size_t, size_t > repeats; bool lower = islower(s[0]); bool upper = isupper(s[0]); bool digit = isdigit(s[0]); for (size_t i = 1; i < length; i++) { if (s[i] == s[i-1]) { repeats[i-1] = 2; } auto c = s[i]; if ( isdigit( c ) ) { digit = true; } else if ( islower( c ) ) { lower = true; } else if ( isupper( c ) ) { upper = true; } } const size_t RepeatMerged = UINT_MAX; for (size_t i = length - 1; i > 0; i--) { auto index = i; if (repeats[index] > 0 && repeats[index-1] > 0) { repeats[index-1] += repeats[index] - 1; repeats[index] = RepeatMerged; } } vector< size_t > multisomes; for (auto r : repeats) { if (r.second >= 3 && r.second != RepeatMerged) { multisomes.push_back(r.first); } } auto sweepMultisomes = [&]() { multisomes.erase( remove_if(multisomes.begin(), multisomes.end(), [&](size_t i) { return repeats[i] < 3; }), multisomes.end() ); }; size_t ret = 0; if (length > 20) { auto d = length - 20; ret += d; for (auto i : multisomes) { auto & r = repeats[i]; while ( d > 0 && r % 3 == 0 ) { r--; length--; d--; } } sweepMultisomes(); for (auto i : multisomes) { auto & r = repeats[i]; while ( d >= 2 && r % 3 == 1 ) { r -= 2; length -= 2; d -= 2; } } sweepMultisomes(); for (auto i : multisomes) { if (d == 0) { break; } auto & r = repeats[i]; auto dr = min( d, r - (3 - 1) ); r -= dr; length -= dr; d -= dr; } sweepMultisomes(); } size_t x = 0; if (!lower) { x++; } if (!upper) { x++; } if (!digit) { x++; } if (length < 6) { x = max(x, 6 - length); } size_t y = 0; for (auto i : multisomes) { y += repeats[i] / 3; } ret += max(x, y); return ret; }};
Runtime: 0 ms
- [算法分析与设计] leetcode 每周一题: 420. Strong Password Checker
- 420. Strong Password Checker [leetcode]
- [leetcode]Strong Password Checker
- [算法分析与设计] leetcode 每周一题: 135. Candy
- [算法分析与设计] leetcode 每周一题: 078. Subsets
- [算法分析与设计] leetcode 每周一题: Word Ladder
- [算法分析与设计] leetcode 每周一题: Surrounded Regions
- [Leetcode] 420. Strong Password Checker 解题报告
- 420. Strong Password Checker
- 420. Strong Password Checker
- 420. Strong Password Checker
- [LeetCode]420. Strong Password Checker深入浅出算法讲解和代码示例
- leetcode 420. Strong Password Checker 密码强度检查器
- [算法分析与设计] leetcode 每周一题: 201. Bitwise AND of Numbers Range
- [算法分析与设计] leetcode 每周一题: 162. Find Peak Element
- [算法分析与设计] leetcode 每周一题: 62. Unique Paths
- [算法分析与设计] leetcode 每周一题: 667. Beautiful Arrangement II
- [算法分析与设计] leetcode 每周一题: 215. Kth Largest Element in an Array
- 一些场景的优化方案和解决方案
- mysql之 远程连接 mysql 很慢,本地连接 mysql 很快 (skip-name-resolve)
- gson&&fastjson
- 输出价格相同的书名
- 字符串数组初始化相关问题总结
- [算法分析与设计] leetcode 每周一题: 420. Strong Password Checker
- 实验八 常见网络测试命令--自我操作
- 延拓版扫雷
- python多进程、多线程、协程向mysql插入10000条数据
- QA(二):利用Attention机制,带着问题阅读
- smo_sensorless pmsm控制中滑模增益K的选取
- ==和equals区别&comparable和comparator区别
- BZOJ1007 [HNOI2008]水平可见直线 贪心+栈
- 快速排序java实现