Hash 如何在字符串(或大文件)中查找第一个非重复/唯一字符(或url)

Hash 如何在字符串(或大文件)中查找第一个非重复/唯一字符(或url),hash,Hash,这是一个面试问题。我努力想想出我想要的解决办法,但还没有成功 O(n^2)时间的方法在O(1)空间中非常明显,其中n是字符串长度/URL总数 可以获得需要额外空间的O(n)解。如果字符串中的第一个字符不重复,请从字符串的末尾开始,然后向前扫描。使用位数组跟踪到目前为止出现的字符值。如果尚未看到某个字符(即当前索引右侧),请将此字符设置为“可能不重复”字符。这将随着向左处理扫描而更新。当到达第一个索引时,最后一个“之前未看到”字符就是结果。对于ASCII字符集,这是一个可以接受的解决方案;因为它只

这是一个面试问题。我努力想想出我想要的解决办法,但还没有成功

O(n^2)时间的方法在O(1)空间中非常明显,其中n是字符串长度/URL总数

可以获得需要额外空间的O(n)解。如果字符串中的第一个字符不重复,请从字符串的末尾开始,然后向前扫描。使用位数组跟踪到目前为止出现的字符值。如果尚未看到某个字符(即当前索引右侧),请将此字符设置为“可能不重复”字符。这将随着向左处理扫描而更新。当到达第一个索引时,最后一个“之前未看到”字符就是结果。对于ASCII字符集,这是一个可以接受的解决方案;因为它只需要256位数组。但是,对于UNICODE字符集,空间复杂度更高。对于文件中的非重复URL,使用哈希表可能适用类似的方法。在这里,空间是实现散列的主要考虑因素,比如存储URL以防止可能的冲突


我正在寻找一些更好的解决方案,时间复杂度为O(n),空间复杂度为常数或对数。请用C语言、C++语言或java语言来分享你的想法。谢谢。

通用算法或多或少是显而易见的(序列只有一次)-伪代码,抱歉:)

唯一剩下的部分是要选择的数据结构集。如果
|U |
是集合域的大小(例如字母表),则根据
|s |/|U |
的预期最大值,我们决定使用位向量还是哈希表。(请注意,即使对于一个巨大的字母表,如果我们希望出现大多数字母,那么位向量也比哈希表好)


还请注意,为了使用位向量,这意味着您必须能够对元素进行排序,即将它们映射到
[0..n)
中的一个数字。当我们谈到字符时,这很简单,但对于其余的输入类型则不然。

我使用哈希映射来获取第一个不重复的字符

因此,我们可以通过顺序读取字符串中的所有字符并记录每个字符出现的次数来创建哈希映射。创建哈希映射后,我们可以顺序读取条目以查看哪个条目的计数为1。此算法的运行时间是多少?我们有O(n)创建哈希映射和另一个O(n)来读取条目。这将导致运行时为O(n)+O(n)=O(2n)=O(n)

代码:

public static Character getNonRepeated(String str){
    Character retc = null;
    int n = 0;
    Map<Character,Integer> charCounter=new HashMap<Character,Integer>(); 

    for (int i = 0; i < str.length() ; i++){
        if (charCounter.containsKey(str.charAt(i))) {
            charCounter.put(str.charAt(i), charCounter.get(str.charAt(i))+1);                               
        }else{
            charCounter.put(str.charAt(i), 1);              
        }
    }

    for (int i = 0; i < str.length() ; i++){
        if (charCounter.get(str.charAt(i)) == 1){
            retc =  str.charAt(i);
        }
    }
    return retc;
}
公共静态字符getNonRepeated(字符串str){
字符retc=null;
int n=0;
Map charCounter=new HashMap();
对于(int i=0;i
您通过使用char(或url)/string(或bigfile)来解决问题。只需选择一个,但不能同时选择两个。或者可以分为子问题A和B。无论哪种方式,我肯定这都是一个重复。
public static Character getNonRepeated(String str){
    Character retc = null;
    int n = 0;
    Map<Character,Integer> charCounter=new HashMap<Character,Integer>(); 

    for (int i = 0; i < str.length() ; i++){
        if (charCounter.containsKey(str.charAt(i))) {
            charCounter.put(str.charAt(i), charCounter.get(str.charAt(i))+1);                               
        }else{
            charCounter.put(str.charAt(i), 1);              
        }
    }

    for (int i = 0; i < str.length() ; i++){
        if (charCounter.get(str.charAt(i)) == 1){
            retc =  str.charAt(i);
        }
    }
    return retc;
}