简体   繁体   中英

Check anagrams existence

Compare 2 Strings and return if they are anagrams or not.

I have a working code:

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
    }

  }
}

It outputs TRUE for str1, str2 and FALSE for str1, str3 as it should.

I did this using hashmaps though, and I was wondering if this is efficient. How can I calculate the efficiency of this? What is a more efficient method?

Efficiency: Seems like 2 O(n) calls and the hashmap calls are all O(1) . Explain?

The complexity is O(n) in your case. There is no way the last hash compare is bigger than O(n), and the complexity could be in the worst case 3*O(n) that means O(n) per total.

I have a suggestion to improve your solution:

  • You can use a simple char[26] array instead of hashmap since you have only 26 letters.
  • Since your array has only 0 values, you only have to do ++array[String.valueOf(str1.charAt(i)) - 97] (no if/else required)
  • In the second for, you decrement for each character --array[String.valueOf(str1.charAt(i)) - 97] (no if/else required)
  • For the final step you go through the 26 items and you print "is not anagram" if you find array[i] != 0 and return...or print "is anagram" after this for

It's still O(n), but uses less memory I think and the last step is clearer..because you have O(27) constant, that is O(1)

Edited: I updated the code because I forgot you use java and not c++, sorry. 97 is the char value of 'a' used to normalize the letters from 97-122 to 0-25

The computational complexity of your implementation is O(n) , assuming n is the number of characters for each string, all having the same length. You have two operations:

  • Creating a HashMap is O(n): For each of the n chars you do one lookup and one insert, which is O(1)
  • Comparing two HashMaps is also O(n): For each key in one, you look it up in the other and compare the two values, which is O(1)

Together, these operations still run in O(n). This assumes that your HashMap implementation does not have too many collisions for each bucket.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM