概要
在编程中,检查一个字符串中所有字符是否全都不同是一个常见问题。以下是两种常见的解决方案:使用集合(Set)和位运算(Bit Manipulation)。每种方法都有其优点和适用场景。本文将详细介绍这两种方法,包括其实现代码和分析
解法一:利用 Set 不可重复性
使用集合(Set)是一种直观且易于理解的方法。集合的基本特性是其元素是唯一的,因此可以利用这一特性来检查字符串中的重复字符。下面展示 代码代码
。
class Solution {
public boolean isUnique(String astr) {
boolean flag = false;
HashSet<Character> hashset = new HashSet<>();
for(char s : astr.toCharArray())//先转化为字符数组,再循环遍历
{
if(!hashset.add(s))
{
return flag;
}
}
flag = true;
return flag;
}
}
代码解析
- 创建集合:首先,创建一个 HashSet 对象,用于存储字符串中的字符。
- 遍历字符串:将字符串转换为字符数组,然后遍历每个字符。
- 检查重复:在每次插入字符到集合时,使用 add 方法。如果字符已经存在于集合中,add 方法会返回 false,我们就可以立即返回 false,表示字符串中存在重复字符。
- 返回结果:如果遍历完所有字符后没有发现重复,返回 true。
优点与缺点
- 优点:代码简单易懂,适用于大部分应用场景。
- 缺点:额外使用了空间来存储字符,空间复杂度为 O(n),其中 n 是字符串的长度。
解法二:位运算解决
位运算是一种高效的解决方案,特别适用于字符集大小固定(如仅包含大写字母)的情况。该方法利用整数的二进制位来表示字符的出现情况。下面展示 实现代码
。
class Solution {
public boolean isUnique(String astr) {
long bits = 0;
boolean flag = false;
int size = astr.length();
for(int i = 0;i<size;i++)
{
int mov = astr.charAt(i)-'A';
if((bits&(1L<<mov))!=0)//(按位相与等于1)重复,返回false
{
return flag;
}else
//标记当前位置有这个字符
{
bits |= (1L<<mov);
}
}
flag = true;
return flag;
}
}
代码解析
- 初始化位标记:使用 long 类型的 bits 变量来记录字符的出现情况。每个位代表一个字符。
- 遍历字符串:对于每个字符,计算其在二进制中的位置 mov。例如,对于字符 ‘A’,mov 的值为 0,对于字符 ‘B’,mov 的值为 1,以此类推。
- 检查重复:使用位运算检查 bits 中相应的位是否已经被设置。如果该位已被设置(即 bits & (1L << mov) 不为 0),说明字符已经出现过。
- 设置标记:如果字符未出现过,设置 bits 中相应的位。
- 返回结果:遍历完所有字符后,如果没有发现重复,返回 true。
优点与缺点
- 优点:时间复杂度为 O(n),空间复杂度为 O(1)(不考虑输入的大小)。在字符集较小的情况下(如仅包含大写字母),非常高效。
- 缺点:实现相对复杂,适用范围有限。如果字符集较大或者包含特殊字符,可能需要调整位运算的实现方式。
结论
选择合适的方法来解决问题取决于具体的需求和限制。使用集合的方法更直观且通用,而位运算方法在特定条件下能提供更高的效率。