12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- func strongPasswordChecker(s string) int {
- // Missing: insert/delete/replace
- // Too short: insert
- // Too long: delete
- // Repeat: insert/delete/replace
- n := len(s)
- if n == 0 {
- return 6
- }
- a, A, d, cnt := 1, 1, 1, 0 // Find the cnt of missing and repeat
- repeat := make([]int, 0)
- pre := rune(s[0])
- for _, r := range s {
- if 'a' <= r && r <= 'z' {
- a = 0
- } else if 'A' <= r && r <= 'Z' {
- A = 0
- } else if '0' <= r && r <= '9' {
- d = 0
- }
- if r == pre {
- cnt++
- } else {
- if 3 <= cnt {
- repeat = append(repeat, cnt)
- }
- cnt = 1
- pre = r
- }
- }
- if 3 <= cnt {
- repeat = append(repeat, cnt)
- }
- miss := a + A + d
- if n < 6 {
- return miss + maxInt(0, 6-n-miss) // Repeat && missing can be both solved by insert
- }
- exceed, replace, m := maxInt(0, n-20), 0, len(repeat)
- res := exceed
- for k := 1; k <= 2; k++ { // Smaller k first, cauz aaa -> aa: 1 step, aaaa -> xaa: 2 step
- for i := 0; i < m && 0 < exceed; i++ {
- if repeat[i] < 3 || repeat[i]%3 != k-1 {
- continue
- }
- dec := minInt(exceed, k)
- repeat[i], exceed = repeat[i]-dec, exceed-dec
- }
- }
- for i := 0; i < m; i++ {
- if 3 <= repeat[i] && 0 < exceed {
- dec := minInt(exceed, repeat[i]-2) // 3k+2 -> 2 to make exceed == 0
- repeat[i], exceed = repeat[i]-dec, exceed-dec
- }
- if 3 <= repeat[i] {
- replace += repeat[i] / 3
- }
- }
- return res + maxInt(miss, replace)
- }
- func minInt(x, y int) int {
- if x < y {
- return x
- }
- return y
- }
- func maxInt(x, y int) int {
- if x < y {
- return y
- }
- return x
- }
|