Two strings are said to be anagrams of each other if the letters of one string may be rearranged to make the other string. For example, the words 'elvis' and 'lives' are anagrams.
In this problem you’ll be given two strings. Your job is to find if the two strings are anagrams of each other or not. If they are not anagrams then find the lexicographically smallest palindrome (in lowercase alphabets) that may be appended to the end of either one of the two strings so that they become anagrams of each other.
The lower and upper case letters are considered equivalent. The number of spaces or any other punctuation or digit is not important.
One string is called lexicographically smaller than another if, at the first position where they differ the first one has smaller alphabet. For example, the strings 'hello' and 'herd' first differ at the third alphabet; 'l' is smaller than 'r', so 'hello' is lexicographically smaller than 'herd'.
A Palindrome is a string that is the same when read forward or backward. For example, the string 'bird rib' is a palindrome, whereas 'hello' is not.
Input:
The first line of the input contains a number T, the number of test cases. T test cases follow. Each test case consists of two lines, one string in each line.
Output:
For each test case output a single line. Print ‘YES’ (without the quotes) if the two strings are anagrams of each other. If they are not, then print the lexicographically smallest palindromic string as discussed above. If no such string exists, then print ‘NO LUCK’ (without the quotes).
Constraints:
\$1 \le T \le 100\$
\$1 \le \text{length of the strings} \le 100\$
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
* Created by ankur on 20-10-2015.
*/
public class Anagrams {
private static final String NO_LUCK = "NO LUCK";
private static final String YES = "YES";
public static void main(String... str) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int totalInput = Integer.parseInt(reader.readLine());
StringBuilder output = new StringBuilder(totalInput);
while (totalInput > 0) {
totalInput--;
String inputString1 = reader.readLine().trim().toLowerCase();
String inputString2 = reader.readLine().trim().toLowerCase();
String result = isAnagramPossible(inputString1, inputString2);
output.append(result);
output.append("\n");
}
System.out.println(output);
}
private static String isAnagramPossible(String a, String b){
int[] returnedArray = isAnagram(a,b);
/*System.out.println(returnedArray.length);
for (int i:returnedArray){
System.out.println(i);
}*/
int sum = 0,oddCount = 0;
for (int i:returnedArray) {
if ((i & 1) != 0){
oddCount += 1;
}
sum += i;
}
if(sum == 0){
return YES;
}
// Handling summing 1 case otherwise will get
// java.lang.ArrayIndexOutOfBoundsException: 0 in
// constructPalindrome function
else if(sum == 1){
for (int i= 0; i < 26; i++){
if (returnedArray[i] == 1){
return String.valueOf((char)('a' + i));
}
}
}
else if(oddCount > 1){
return NO_LUCK;
}
System.out.println("Test");
String palindromeAdd = constructPalindrome(returnedArray);
return palindromeAdd;
}
/*
Constructing the palindrome string
*/
private static String constructPalindrome(int[] charFrequenciesDiff){
Character[] palindrome;
System.out.println("Test");
List<Character> characterList= new ArrayList<>();
char midChar = ' ';
boolean handleOdd = false;
for (int i = 0; i< 26; i++ ){
int total=charFrequenciesDiff[i];
if((total & 1) == 1){
handleOdd = true;
total -= 1;
midChar = (char)('a' + i);
}
while (total>0){
total--;
characterList.add((char)('a' + i)); //
}
}
palindrome = characterList.toArray(new Character[characterList.size()]);
int palindromeLen = palindrome.length;
Arrays.sort(palindrome);
if (palindromeLen == 1 || palindrome[0] == palindrome[palindromeLen - 1]){
String str1= Arrays.toString(palindrome);
str1 = str1.substring(1, str1.length()-1).replaceAll(", ", "");
return str1 ;
}
StringBuilder sb = new StringBuilder();
int i =0;
while(i < palindromeLen){
sb.append(palindrome[i]);
i += 2;
}
StringBuilder reverse = new StringBuilder(sb);
// Handle Odd case.
if(handleOdd){
sb.append(midChar);
}
sb.append(reverse.reverse());
return sb.toString();
}
private static int[] isAnagram(String a, String b){
int[] returnArray = new int[26];
char[] a1 = new char[26];
char[] a2 = new char[26];
Arrays.fill(returnArray,0);
Arrays.fill(a1, ' ');
Arrays.fill(a2, ' ');
char[] aArray = a.toCharArray();
char[] bArray = b.toCharArray();
for (int i = 0, len = a.length(); i < len; i++ ){
if(Character.isAlphabetic(aArray[i])) {
int pos = (int) aArray[i] - (int) 'a';
a1[pos] += 1;
}
}
for (int i = 0, len = b.length(); i < len; i++ ){
if(Character.isAlphabetic(bArray[i])) {
int pos = (int) bArray[i] - (int) 'a';
a2[pos] += 1;
}
}
int j =0;
boolean is_true = true;
while (j < 26 && is_true){
if (a1[j] == a2 [j]){
j = j+ 1;
}
else {
is_true = false;
}
}
if (!is_true){
for (int i = 0; i < 26; i++){
returnArray[i] = Math.abs(a1[i] - a2[i]);
}
}
return returnArray;
}
}
Output time: 0.1619sec
How can I further improve the performance of this code in terms of time? Avoid repetitions if I did it somewhere. Also, lambdas elude me.