Skip to content

Commit cc01faf

Browse files
authored
Merge pull request #1015 from shreyash3087/add/leetcode-420
Docs: Added Solution to Leetcode 420
2 parents a4e0660 + f5b1e09 commit cc01faf

File tree

2 files changed

+245
-1
lines changed

2 files changed

+245
-1
lines changed

dsa-problems/leetcode-problems/0400-0499.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ export const problems = [
134134
"problemName": "420. Strong Password Checker",
135135
"difficulty": "Hard",
136136
"leetCodeLink": "https://leetcode.com/problems/strong-password-checker",
137-
"solutionLink": "#"
137+
"solutionLink": "/dsa-solutions/lc-solutions/0400-0499/strong-password-checker"
138138
},
139139
{
140140
"problemName": "421. Maximum XOR of Two Numbers in an Array",
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
---
2+
id: strong-password-checker
3+
title: Strong Password Checker
4+
sidebar_label: 0420 - Strong Password Checker
5+
tags:
6+
- Greedy
7+
- Dynamic Programming
8+
- Heap
9+
description: "This is a solution to the Strong Password Checker problem on LeetCode."
10+
---
11+
12+
## Problem Description
13+
14+
A password is considered strong if the below conditions are all met:
15+
16+
- It has at least 6 characters and at most 20 characters.
17+
- It contains at least **one lowercase letter**, at least **one uppercase** letter, and at least **one digit**.
18+
- It does not contain three repeating characters in a row (i.e., `"Baaabb0"` is weak, but `"Baaba0"` is strong).
19+
20+
Given a string password, return the minimum number of steps required to make password strong. if password is already strong, return 0.
21+
22+
In one step, you can:
23+
24+
- Insert one character to password,
25+
- Delete one character from password, or
26+
- Replace one character of password with another character.
27+
28+
### Examples
29+
30+
**Example 1:**
31+
32+
```
33+
Input: password = "a"
34+
Output: 5
35+
Explanation: The password needs additional characters, an uppercase letter, and a digit to meet the criteria.
36+
```
37+
38+
**Example 2:**
39+
40+
```
41+
Input: password = "aA1"
42+
Output: 3
43+
Explanation: The password needs more characters to reach the minimum length of 6.
44+
```
45+
46+
### Constraints
47+
48+
- `1 <= password.length <= 50`
49+
- `password` consists of letters, digits, dot `'.'` or exclamation mark `'!'`.
50+
51+
## Solution for Strong Password Checker
52+
53+
### Approach
54+
55+
- A strong password should contain at least one lowercase letter, one uppercase letter, and one number.
56+
- It should avoid having the same character repeated three times consecutively and be between 6 and 20 characters long.
57+
58+
The code achieves this by following these steps:
59+
60+
1. Utilizes a “requirements” checklist to keep track of the first three criteria (initially unchecked).
61+
2. Maintains a record of character repetitions.
62+
3. Examines each character in the text:
63+
- If different from the previous character, checks off requirements if not met.
64+
- If the same as the previous character, counts consecutive repetitions.
65+
4. Sorts the repeated characters list by the number of repetitions.
66+
5. Adjusts the text:
67+
- For text longer than 20 characters, removes one repeated character in sequences of three or more.
68+
- For texts without such sequences, removes one character from the repeated character list.
69+
- Continues until the text is 20 characters or less.
70+
6. Calculates the number of characters needed to make the text at least 6 characters long (if it’s shorter).
71+
7. Totals all the changes made to meet the rules, providing the minimum number of changes required to create a strong password.
72+
73+
## Code in Different Languages
74+
75+
<Tabs>
76+
<TabItem value="cpp" label="C++">
77+
<SolutionAuthor name="@Shreyash3087"/>
78+
79+
```cpp
80+
class Solution {
81+
public:
82+
int strongPasswordChecker(string s) {
83+
bitset<3> requirements{111};
84+
list<int> repeats;
85+
auto it = s.begin();
86+
auto it2 = s.end();
87+
while (it != s.end()) {
88+
if (*it != *it2) {
89+
if (requirements.test(0) && islower(*it))
90+
requirements.reset(0);
91+
if (requirements.test(1) && isupper(*it))
92+
requirements.reset(1);
93+
if (requirements.test(2) && isdigit(*it))
94+
requirements.reset(2);
95+
} else {
96+
while (it != s.end() && *it == *it2)
97+
++it;
98+
if (distance(it2, it) != 2)
99+
repeats.push_back(distance(it2, it));
100+
if (it != s.end())
101+
continue;
102+
else
103+
break;
104+
}
105+
it2 = it;
106+
++it;
107+
}
108+
repeats.sort([](const int &lhs, const int &rhs) { return (lhs % 3) < (rhs % 3); });
109+
int ans{0}, len{static_cast<int>(s.size())};
110+
while (len > 20) {
111+
if (!repeats.empty()) {
112+
if (repeats.front() == 3) {
113+
repeats.pop_front();
114+
}
115+
else {
116+
--repeats.front();
117+
repeats.sort([](const int &lhs, const int &rhs) { return (lhs % 3) < (rhs % 3); });
118+
}
119+
++ans;
120+
--len;
121+
}
122+
else {
123+
ans += len - 20;
124+
len = 20;
125+
}
126+
}
127+
int rep_ins{0};
128+
while (!repeats.empty()) {
129+
rep_ins += repeats.front() / 3;
130+
repeats.pop_front();
131+
}
132+
if ((len + rep_ins) < 6) {
133+
rep_ins += 6 - len - rep_ins;
134+
}
135+
ans += max(static_cast<int>(requirements.count()), rep_ins);
136+
return ans;
137+
}
138+
};
139+
```
140+
</TabItem>
141+
<TabItem value="java" label="Java">
142+
<SolutionAuthor name="@Shreyash3087"/>
143+
144+
```java
145+
class Solution {
146+
public int strongPasswordChecker(String s) {
147+
int res = 0, a = 1, A = 1, d = 1;
148+
char[] carr = s.toCharArray();
149+
int[] arr = new int[carr.length];
150+
for (int i = 0; i < arr.length;) {
151+
if (Character.isLowerCase(carr[i])) a = 0;
152+
if (Character.isUpperCase(carr[i])) A = 0;
153+
if (Character.isDigit(carr[i])) d = 0;
154+
int j = i;
155+
while (i < carr.length && carr[i] == carr[j]) i++;
156+
arr[j] = i - j;
157+
}
158+
159+
int total_missing = (a + A + d);
160+
if (arr.length < 6) {
161+
res += total_missing + Math.max(0, 6 - (arr.length + total_missing));
162+
} else {
163+
int over_len = Math.max(arr.length - 20, 0), left_over = 0;
164+
res += over_len;
165+
for (int k = 1; k < 3; k++) {
166+
for (int i = 0; i < arr.length && over_len > 0; i++) {
167+
if (arr[i] < 3 || arr[i] % 3 != (k - 1)) continue;
168+
arr[i] -= Math.min(over_len, k);
169+
over_len -= k;
170+
}
171+
}
172+
for (int i = 0; i < arr.length; i++) {
173+
if (arr[i] >= 3 && over_len > 0) {
174+
int need = arr[i] - 2;
175+
arr[i] -= over_len;
176+
over_len -= need;
177+
}
178+
if (arr[i] >= 3) left_over += arr[i] / 3;
179+
}
180+
res += Math.max(total_missing, left_over);
181+
}
182+
return res;
183+
}
184+
}
185+
```
186+
187+
</TabItem>
188+
<TabItem value="python" label="Python">
189+
<SolutionAuthor name="@Shreyash3087"/>
190+
191+
```python
192+
class Solution(object):
193+
def strongPasswordChecker(self, s):
194+
missing_type = 3
195+
if any('a' <= c <= 'z' for c in s): missing_type -= 1
196+
if any('A' <= c <= 'Z' for c in s): missing_type -= 1
197+
if any(c.isdigit() for c in s): missing_type -= 1
198+
199+
change = 0
200+
one = 0
201+
two = 0
202+
p = 2
203+
while p < len(s):
204+
if s[p] == s[p-1] == s[p-2]:
205+
length = 2
206+
while p < len(s) and s[p] == s[p-1]:
207+
length += 1
208+
p += 1
209+
change += length // 3
210+
if length % 3 == 0: one += 1
211+
elif length % 3 == 1: two += 1
212+
else:
213+
p += 1
214+
215+
if len(s) < 6:
216+
return max(missing_type, 6 - len(s))
217+
elif len(s) <= 20:
218+
return max(missing_type, change)
219+
else:
220+
delete = len(s) - 20
221+
change -= min(delete, one)
222+
change -= min(max(delete - one, 0), two * 2) // 2
223+
change -= max(delete - one - 2 * two, 0) // 3
224+
return delete + max(missing_type, change)
225+
226+
```
227+
</TabItem>
228+
</Tabs>
229+
230+
## Complexity Analysis
231+
232+
### Time Complexity: $O(N)$
233+
234+
> **Reason**: The code iterates through the input string once and performs various operations such as checking character types, counting repeated characters, and maintaining a list of repeats.
235+
236+
### Space Complexity: $O(N)$
237+
238+
> **Reason**: The space complexity is linear because the size of the repeats list is proportional to the length of the input
239+
240+
## References
241+
242+
- **LeetCode Problem**: [Strong Password Checker](https://leetcode.com/problems/strong-password-checker/description/)
243+
244+
- **Solution Link**: [Strong Password Checker](https://leetcode.com/problems/strong-password-checker/solutions/)

0 commit comments

Comments
 (0)