Find anagram of input on set of strings..?

后端 未结 3 1045
小鲜肉
小鲜肉 2021-02-10 13:59

Given a set of strings (large set), and an input string, you need to find all the anagrams of the input string efficiently. What data structure will you use. And using that, how

3条回答
  •  醉话见心
    2021-02-10 14:21

    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;
    /*
     *Program for Find Anagrams from Given A string of Arrays.
     *
     *Program's Maximum Time Complexity is O(n) + O(klogk), here k is the length of word.
     *
     * By removal of Sorting, Program's Complexity is O(n) 
     *  **/
    public class FindAnagramsOptimized {
        public static void main(String[] args) {
            String[] words = { "gOd", "doG", "doll", "llod", "lold", "life", 
    "sandesh", "101", "011", "110" };
            System.out.println(getAnaGram(words));
        }
        // Space Complexity O(n)
        // Time Complexity O(nLogn)
        static Set getAnaGram(String[] allWords) {
            // Internal Data Structure for Keeping the Values
            class OriginalOccurence {
                int occurence;
                int index;
            }
            Map mapOfOccurence = new HashMap<>();
            int count = 0;
            // Loop Time Complexity is O(n)
        // Space Complexity O(K+2K), here K is unique words after sorting on a
    
        for (String word : allWords) {
            String key = sortedWord(word);
    
            if (key == null) {
                continue;
            }
            if (!mapOfOccurence.containsKey(key)) {
                OriginalOccurence original = new OriginalOccurence();
                original.index = count;
                original.occurence = 1;
                mapOfOccurence.put(key, original);
            } else {
                OriginalOccurence tempVar = mapOfOccurence.get(key);
                tempVar.occurence += 1;
                mapOfOccurence.put(key, tempVar);
            }
            count++;
        }
    
        Set finalAnagrams = new HashSet<>();
    
        // Loop works in O(K), here K is unique words after sorting on
        // characters
        for (Map.Entry anaGramedWordList : mapOfOccurence.entrySet()) {
            if (anaGramedWordList.getValue().occurence > 1) {
                finalAnagrams.add(allWords[anaGramedWordList.getValue().index]);
            }
        }
    
        return finalAnagrams;
    }
    
    // Array Sort works in O(nLogn)
    // Customized Sorting for only chracter's works in O(n) time.
    private static String sortedWord(String word) {
    
        // int[] asciiArray = new int[word.length()];
        int[] asciiArrayOf26 = new int[26];
        // char[] lowerCaseCharacterArray = new char[word.length()];
        // int characterSequence = 0;
        // Ignore Case Logic written in lower level
        for (char character : word.toCharArray()) {
            if (character >= 97 && character <= 122) {
                // asciiArray[characterSequence] = character;
                if (asciiArrayOf26[character - 97] != 0) {
                    asciiArrayOf26[character - 97] += 1;
                } else {
                    asciiArrayOf26[character - 97] = 1;
                }
            } else if (character >= 65 && character <= 90) {
                // asciiArray[characterSequence] = character + 32;
                if (asciiArrayOf26[character + 32 - 97] != 0) {
                    asciiArrayOf26[character + 32 - 97] += 1;
                } else {
                    asciiArrayOf26[character + 32 - 97] = 1;
                }
            } else {
                return null;
            }
    
            // lowerCaseCharacterArray[characterSequence] = (char)
            // asciiArray[characterSequence];
            // characterSequence++;
        }
        // Arrays.sort(lowerCaseCharacterArray);
    
        StringBuilder sortedWord = new StringBuilder();
        int asciiToIndex = 0;
        // This Logic uses for reading the occurrences from array and copying
        // back into the character array
        for (int asciiValueOfCharacter : asciiArrayOf26) {
            if (asciiValueOfCharacter != 0) {
                if (asciiValueOfCharacter == 1) {
                    sortedWord.append((char) (asciiToIndex + 97));
                } else {
                    for (int i = 0; i < asciiValueOfCharacter; i++) {
                        sortedWord.append((char) (asciiToIndex + 97));
                    }
                }
            }
            asciiToIndex++;
        }
        // return new String(lowerCaseCharacterArray);
        return sortedWord.toString();
    }
    }
    

提交回复
热议问题