使用HashMap减少时间复杂度,还是有更好的方法?

时间:2010-12-29 08:58:06

标签: java algorithm hash hashmap complexity-theory

是的,这是一个较旧的考试,我用它来准备我自己的考试。我们给出以下方法:

public static void Oorspronkelijk()
{
    String bs = "Dit is een boodschap aan de wereld";
    int max = -1;
    char let = '*';
    for (int i=0;i<bs.length();i++) {
        int tel = 1;
        for (int j=i+1;j<bs.length();j++) {
            if (bs.charAt(j) == bs.charAt(i)) tel++;
        }

        if (tel > max) {
            max = tel;
            let = bs.charAt(i);
        }
    }

    System.out.println(max + " keer " + let);
}

问题是:

  1. 输出是什么? - 由于代码只是确定最常出现字符的算法,因此输出为“6 keer”(6倍空间)
  2. 此代码的时间复杂度是多少? 相当确定它是O(n²),除非有人另有想法?
  3. 你能减少时间复杂度吗?若然,怎么办?
  4. 嗯,你可以。我已经收到了一些帮助,并设法获得以下代码:

    public static void Nieuw()
    {
        String bs = "Dit is een boodschap aan de wereld";
        HashMap<Character, Integer> letters = new HashMap<Character, Integer>();
        char max = bs.charAt(0);
        for (int i=0;i<bs.length();i++) {
            char let = bs.charAt(i);
            if(!letters.containsKey(let)) {
                letters.put(let,0);
            }
    
            int tel = letters.get(let)+1;
            letters.put(let,tel);
    
            if(letters.get(max)<tel) {
                max = let;
            }
        }
    
        System.out.println(letters.get(max) + " keer " + max);
    }
    

    但是,我不确定这个新代码的时间复杂性:它是O(n)因为你只使用一个for循环,或者我们需要使用HashMap的get方法使得它成为O( n log n)?

    如果有人知道减少时间复杂度的更好方法,请告诉我们! :)

5 个答案:

答案 0 :(得分:2)

新代码的时间复杂度为O(n) - 这是因为hashmap查找是一个恒定时间操作,而常量时间操作不会影响顺序。

我可以提出一个建议,只是一个优化(不会产生巨大的差异) - 不是一个重大的改变而不会影响顺序 - 是你可以使用一个int数组而不是一个哈希映射来跟踪每个角色的数量。只需使用与char相当的int值作为数组的索引。

答案 1 :(得分:0)

哈希函数get操作是O(1),因此您的解决方案的时间复杂度为O(n)。 你不能做得更好,因为任何解决方案都要求你至少读一次整个输入。

答案 2 :(得分:0)

我认为是O(n)。因为在HashMap中搜索只是O(1)

for (int i=0;i<bs.length();i++) { // O(n)
    char let = bs.charAt(i); // O(1)
    if(!letters.containsKey(let)) { // O(1)
        letters.put(let,0);
    }

整体复杂度为O(n)

答案 3 :(得分:0)

为确保HashMap始终具有O(1)的时间复杂度,您可能必须输入正确的initialCapacity。您需要知道bs String将具有的完整域值。

假设,     1.上下病例将分开处理。     2.字符串只有字母和空格字符

初始负荷能力应大于,26(小写)+ 26(大写)+ 1(空格)= 53

53 + 25%(53)= 53 + 13.25 + 2.75(缓冲液)= 69。

所以hashmap的启动可能如下所示,

HashMap&lt; Character,Integer&gt; letters = new HashMap&lt; Character,Integer&gt;(69);

答案 4 :(得分:0)

Hashmap是O(1),但在这里你也可以使用数组,因为字母数量相当小(只有256)你也可以使用数组。这也是O(1),但更快,使用更少的内存,而且更简单:

String bs = "Dit is een boodschap aan de wereld";
int letters[] = new int[256];
char max = 0;
for (int i=0;i<bs.length();i++) {
    char let = bs.charAt(i);
    ++letters[let];

    if(letters[max] < letters[let]) {
        max = let;
    }
}

System.out.println(letters[max] + " keer " + max);