检查anagrams的存在

时间:2017-01-04 07:48:22

标签: java algorithm

  

比较2个字符串并返回它们是否为字谜。

我有一个正常工作的代码:

import java.util.*;
public class HelloWorld {
  public static void main(String[] args) {
    HashMap<String, Integer> map= new HashMap<>();
    HashMap<String, Integer> map1= new HashMap<>();
    String str1 = "abaa";
    String str2 = "baaa";
    String str3 = "bbbb"; //false


      for(int i=0 ; i < str1.length(); i++){ //sr1 map
   String value = String.valueOf(str1.charAt(i));

    if (map1.containsKey(value)) {

    map1.put(value, map1.get(value) + 1);


} else {
    // No such key
    map1.put(value, 1);
}



    }


    for(int i=0 ; i < str1.length(); i++){ //str2 map
   String value = String.valueOf(str3.charAt(i));

    if (map.containsKey(value)) {

    map.put(value, map.get(value) + 1);


} else {
    // No such key
    map.put(value, 1);
}



    }

    if(map1.equals(map)){
        System.out.println("true"); //anagrams
    } else{
        System.out.println("FalsE"); //not anagrams
    }

  }
}

它为str1, str2输出 TRUE ,为FALSE输出str1, str3

我这样做是使用哈希映射,我想知道这是否有效。 如何计算效率呢?什么是更有效的方法?

效率:似乎有2 O(n)次来电,hashmap来电都是O(1)。解释

2 个答案:

答案 0 :(得分:0)

在你的情况下,复杂性是O(n)。最后一个哈希比较没有办法比O(n)大,并且复杂性可能在最坏的情况下为3 * O(n),这意味着每个总数为O(n)。

我有建议改善您的解决方案:

  • 您可以使用简单的char [26]数组而不是hashmap,因为您只有26个字母。
  • 由于你的数组只有0个值,你只需做++ array [String.valueOf(str1.charAt(i)) - 97](如果需要/则不需要)
  • 在第二个中,你减少每个字符--array [String.valueOf(str1.charAt(i)) - 97](如果/其他需要,则为no)
  • 在最后一步中,你会看到26个项目,如果你发现数组[i]!= 0并且返回...或者打印“是anagram”之后打印“is not anagram”

它仍然是O(n),但我认为使用的内存更少,最后一步更清晰。因为你有O(27)常数,那就是O(1)

编辑:我更新了代码,因为我忘了你使用java而不是c ++,抱歉。 97是'a'的char值,用于将字母从97-122标准化为0-25

答案 1 :(得分:0)

您的实现的计​​算复杂度为 O(n),假设n是每个字符串的字符数,所有字符都具有相同的长度。您有两个操作:

  • 创建HashMap是O(n):对于每个n个字符,您执行一次查找和一次插入,即O(1)
  • 比较两个HashMaps也是O(n):对于一个中的每个键,你在另一个中查找它并比较两个值,即O(1)

这些操作一起仍在O(n)中运行。这假设您的HashMap实现没有针对每个存储桶的过多冲突。