如何判断字符串中所有字符是否全都不同?

概要

在编程中,检查一个字符串中所有字符是否全都不同是一个常见问题。以下是两种常见的解决方案:使用集合(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)(不考虑输入的大小)。在字符集较小的情况下(如仅包含大写字母),非常高效。
  • 缺点:实现相对复杂,适用范围有限。如果字符集较大或者包含特殊字符,可能需要调整位运算的实现方式。

结论

选择合适的方法来解决问题取决于具体的需求和限制。使用集合的方法更直观且通用,而位运算方法在特定条件下能提供更高的效率。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值