面试题1 判断字符串是否含有重复字符

问题: 写一个方法 输入一个字符串 判断该字符串是否含有重复字符 如果不重复则返回 true 否则返回 false

方法1: 暴力枚举

该方法从字符串首字符开始遍历所有字符  讲字符串里所有其他字符和当前字符相比 一旦出现相同则返回 false  相反  如果循环顺利结束则返回 true

这个方法的时间复杂度是 O(n^2)  空间复杂度是 O(1)

//brute force implementation that runs O(n^2) time, where n is the length of the string
  public boolean bruteForce(String s){
    for(int i=0; i<s.length()-1; i++){
      for(int j=i+1; j<s.length(); j++){
        if(s.charAt(i)==s.charAt(j))  return true;
      }
    }
    return false;
  }

方法2: Hashtable

该方法建立一个 Hashtable  使用 cha r的 hashCode 作为 key  使用 char 本身作为 value  

该方法遍历字符串内所有字符 如果当前字符在 hastable 内已经存在 则返回 false 否则 则插入该字符

该方法提高了时间效率 查找 HashTable 中是否存在一个 value 需要 O(1) 所以总的时间复杂度是 O(n) 

但是由于需要额外的空间建立 Hash Table, 所以空间复杂度也提高到了 O(n)

  //hashtable based implementation that runs O(n) time, where n is the length of the string
  public boolean isUniqueChars(String s){
    Hashtable<Integer, Character> ht = new Hashtable<Integer, Character>();
    for(int i=0; i<s.length(); i++){
      Character cur = (Character)s.charAt(i);
      if(ht.containsValue(cur))  return true;
      ht.put(cur.hashCode(), cur);
    }
    return false;
  }

方法3: boolean array

仔细想一下 其实由于前面的 Hashtable 的 key 和 value 都和当前字符本身有关 我们关心的 又仅仅是有没有相同的字符 所以 value 值其实并不重要 只要保证相同的 char 可以被 hash 到相同的key上(没有碰撞) 我们只需要 key 集合

就可以判断当前字符是否和表内字符重复 

如果我们假设输入字符串的字符集 只是 ASCII, 那么 ASCII 表就可以保证每个不同的字符被 hash 到不同的 key 当中. 这样连使用 Hashtable 都没必要了 使用一个 boolean array 就可以了

下面的方法使用了一个 boolean array 跟踪那些 ASCII 字符已经出现过 array 的 index (相当于 Hashtable 的 key) 就是该字符的 ASCII 码 

此方法讲时间复杂度降低到了 O(n) 而 boolean array 又非常的小且长度固定 我们可以认为空间复杂度依然是 O(1)  所以此方法是最优解

  public boolean isUniqueChars1(String str){
    if(str.length()>128) return false;

    boolean[] char_set = new boolean[256];
    for(int i=0; i<str.length(); i++){
      int val = str.charAt(i);
      if(char_set[val]) return false;
      char_set[val] = true;
    }
    return true;
  }

 

转载于:https://www.cnblogs.com/moechen/p/5052881.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值