leetcode
leetcode 2001 ~ 2050
强密码检验器 II

强密码检验器 II

难度:

标签:

题目描述

代码结果

运行时间: 25 ms, 内存: 15.9 MB


/*
 * 思路:
 * 1. 使用Java Stream API检查各种条件。
 * 2. 使用流处理集合和条件。
 */

import java.util.stream.IntStream;

public class StrongPasswordCheckerStream {
    public static boolean isStrongPassword(String password) {
        if (password.length() < 8) return false;

        boolean hasLower = password.chars().anyMatch(Character::isLowerCase);
        boolean hasUpper = password.chars().anyMatch(Character::isUpperCase);
        boolean hasDigit = password.chars().anyMatch(Character::isDigit);
        boolean hasSpecial = password.chars().anyMatch(ch -> "!@#$%^&*()-+".indexOf(ch) >= 0);
        boolean noConsecutive = IntStream.range(1, password.length())
                                          .noneMatch(i -> password.charAt(i) == password.charAt(i - 1));

        return hasLower && hasUpper && hasDigit && hasSpecial && noConsecutive;
    }
}

解释

方法:

此题解采用正则表达式来检查密码是否满足各项要求。首先检查密码长度是否大于等于8。接着依次检查密码中是否至少包含一个小写字母、一个大写字母、一个数字和一个特殊字符。最后检查密码中是否存在连续相同的字符。如果所有条件都满足,则返回True,否则返回False。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
在正则表达式中使用`(.)\1+`是为了检查什么?这种表达方式是否准确地检测所有连续相同字符的情况?
正则表达式中的`(.)\1+`用于检查密码中是否存在连续相同的字符。其中,`(.)`表示匹配任意单个字符并将其捕获为一个组,`\1`是对前面捕获的组的引用,`+`表示前面的元素出现一次或多次。这种表达方式可以准确地检测所有连续相同字符的情况,因为它会匹配任何连续重复的字符,无论是字母、数字还是特殊字符。
🦆
为什么选择正则表达式作为验证各个条件的主要方法?是否存在其他可能更高效的实现方式?
选择正则表达式作为验证密码条件的主要方法是因为正则表达式提供了一种简洁且强大的方式来匹配模式,从而可以简化代码并减少编程错误。尽管正则表达式在某些情况下可能较慢,存在更高效的实现方式,例如,通过单次遍历字符串并使用简单的条件判断来检查所有必要的密码要求,这可能会比多次执行正则匹配更快,特别是对于较长的密码。
🦆
代码中使用了多次正则表达式匹配。这种方法与单次遍历字符串检查所有条件有何优劣?
多次使用正则表达式匹配的优点在于代码的可读性和简洁性,因为正则表达式能够直观地描述所需匹配的模式。然而,这种方法的缺点是效率较低,因为每次执行正则表达式都需要重新扫描整个字符串,这在密码较长时尤其耗时。相比之下,单次遍历字符串在一次过程中检查所有条件,可以显著提高效率,尤其是对于复杂的密码验证规则。
🦆
正则表达式中检查特殊字符使用了`[!@#$%^&*()\-+]`,其中的连字符`-`是否正确放置,以避免成为范围操作符?
在正则表达式`[!@#$%^&*()\-+]`中,连字符`-`被正确地放置在字符集的最后一位,这样做可以避免其被解释为范围操作符。如果`-`放置在两个字符之间,例如`a-c`, 它会被解释为从`a`到`c`的范围。因此,在这个正则表达式中,`-`作为字面量字符被正确处理。

相关问题