面试题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;
  }

 

posted @ 2015-12-17 04:25  橙喵moe  阅读(624)  评论(0编辑  收藏  举报