1

I am trying to solve this question: https://www.hackerrank.com/challenges/anagram

Here's my code:

import java.util.*;

public class Anagram {

    public static void main(String[] args)
    {
        Scanner reader = new Scanner(System.in);
        int t = reader.nextInt();

        while((t--) > 0)
        {    
            String input = reader.nextLine();

            if((input.length()) % 2 == 1)
                System.out.println(-1);
            else
            {
                int x = input.length();
                int q = (int)(Math.floor((x / 2)));

                String input1 = input.substring(0, q);
                String input2 = input.substring(q, x);

                int [] count2 = new int[26];
                for(int i = 0; i < input2.length(); i++)
                {
                    char ch2 = input2.charAt(i);
                    count2[ch2 - 'a']++;
                }

                // int [] count1 = new int[26];
                for(int i = 0; i < input1.length(); i++)
                {
                    char ch1 = input1.charAt(i);
                    if(count2[i] > 0)
                        count2[ch1 - 'a']--;
                }

                int count = 0;
                for(int j = 0; j < 26; j++)
                {
                    count = count + Math.abs(count2[j]);
                }

                System.out.println(count);
            } 
        }
    }
} 

Sample Input

6
aaabbb
ab
abc
mnop
xyyx
xaxbbbxx

Expected Output

3
1
-1
2
0
1

My output

0
4
1
-1
2
2

Can anyone please tell me where it went wrong? I couldn't find the error...

rbento
  • 5,069
  • 1
  • 40
  • 51
coder101
  • 770
  • 2
  • 9
  • 25
  • I don't know java , is there no way in java to compare a char ? I don't understand why you make an array of char's ?? all you need to do is just iterate through the first half and check if there is a match in the second half. – Scott Selby Mar 22 '15 at 05:02
  • @ScottSelby That should also be done by iterating over 2nd half and check if there is match in 1st half. Essentially, that would be `O(n^2)` algorithm. The one OP is using is `O(n)`. – Rohit Jain Mar 22 '15 at 05:25

4 Answers4

1

You can use this to check if two strings are palindromes:

String original = "something";
String reverse = new StringBuilder(original).reverse().toString();

boolean anagram = original.equals(reverse);
coder101
  • 770
  • 2
  • 9
  • 25
Mateo
  • 29
  • 1
1

Your first output always comes 0, because of this line:

int t = reader.nextInt();

followed by reader.nextLine();. Check this post for more details on that. For quick fix, change that line to:

int t = Integer.parseInt(reader.nextLine());

Now, let's start with the below two statements:

int x = input.length();
int q = (int)(Math.floor((x/2)));

No need to do a Math.floor there. x/2 is an integer division, and will give you integer result only.

Moving to the 2nd for loop. You used the following condition:

if(count2[i]>0)
    count2[ch1-'a']--;

Notice the mistake there in condition? It should be count2[ch1 - 'a'] > 0. And also, you will miss the case where that count is not greater than 0, in which case you would have to do a ++. BTW, since you're anyways doing a Math.abs(), you don't need the condition. Just do a --:

for( int i = 0; i < input1.length(); i++ ) {
    char ch1 = input1.charAt(i);
    count2[ch1-'a']--;
}

BTW, the final result would be count / 2, and not count, because count contains the total mismatch from input1 to input2 and vice-versa. But we just have to fix one of them to match the other. So, just consider half the total mismatch.

Community
  • 1
  • 1
Rohit Jain
  • 195,192
  • 43
  • 369
  • 489
  • thanks that worked perfectly , btw what was the difference between count2[i]>0 and count2[ch1 - 'a'] > 0 – coder101 Mar 22 '15 at 06:27
  • They would not test the same index of `count2` array, if `2nd` character is `'z'` – Rohit Jain Mar 22 '15 at 06:28
  • @coder101 I don't think `count` is the correct result. Did you try running the code, and printing the result. It should be `count / 2`. – Rohit Jain Mar 22 '15 at 06:42
  • yes it got submitted ( passed all test cases ) when i kept the final result to count – coder101 Mar 22 '15 at 06:43
  • please check this question once http://stackoverflow.com/questions/29191565/find-the-number-of-unordered-anagramic-pairs-of-substrings still stuck at this one – coder101 Mar 22 '15 at 06:47
0

As per your question, main logic could be changed to something like below.

Note - I have added only the main logic and excluded the user inputs here.

public static void main(String[] args) {
    String str = "acbacccbaac";
    int len = str.length();
    String str1 = null, str2 = null;
    if(len %2 != 0) {//check for odd length
        str1 = str.substring(0, len/2);
        str2 = str.substring(len/2+1, len);
    }else {//check for even length
        str1 = str.substring(0, len/2);
        str2 = str.substring(len/2, len);
    }
    char[] arr1 = str1.toLowerCase().toCharArray();
    Arrays.sort(arr1);
    char[] arr2 = str2.toLowerCase().toCharArray();
    Arrays.sort(arr2);
    if(Arrays.equals(arr1, arr2))
        System.out.println("Yes");
    else
        System.out.println("No");
}

I implemented this way for the same problem in my HackerRank profile, and works great.

Ram
  • 3,270
  • 4
  • 21
  • 48
0

This is my solution to the prob and it works!

static int anagram(String s) {
        String a = "";
        String b = "";
        if (s.length() % 2 == 0) {
            a = s.substring(0, s.length() / 2);
            b = s.substring((s.length() / 2), s.length());
        }

        if (s.length() % 2 != 0) {
            a = s.substring(0, s.length() / 2);
            b = s.substring((s.length() / 2), s.length());
        }
        if (a.length() == b.length()) {
            char[] aArray = a.toCharArray();
            char[] bArray = b.toCharArray();
            HashMap<Character, Integer> aMap = new HashMap<Character, Integer>();
            HashMap<Character, Integer> bMap = new HashMap<Character, Integer>();
            for (char c : aArray) { // prepare a Hashmap of <char>,<count> for first string
                if (aMap.containsKey(c)) {
                    aMap.put(c, aMap.get(c) + 1);
                } else {
                    aMap.put(c, 1);
                }
            }

            for (char c : bArray) {// prepare a Hashmap of <char>,<count> for second string
                if (bMap.containsKey(c)) {
                    bMap.put(c, bMap.get(c) + 1);
                } else {
                    bMap.put(c, 1);
                }
            }
            int change = 0;
            for (Map.Entry<Character, Integer> entry : bMap.entrySet()) {
                System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
                if (!aMap.containsKey(entry.getKey())) {
                    change += entry.getValue();
                } else {
                    if (entry.getValue() > aMap.get(entry.getKey())) {
                        change += entry.getValue() - aMap.get(entry.getKey());
                    } else {
                        //change += entry.getValue();
                    }
                }
            }
            return change;
        } else {
            return -1;
        }
}
raikumardipak
  • 1,049
  • 1
  • 20
  • 35