66
77/**
88 * Leetcode Problem: https://leetcode.com/problems/find-all-anagrams-in-a-string/
9- *
9+ *
1010 * @author rampatra
1111 * @since 2019-04-13
1212 */
1313public class AnagramsInString {
1414
15+ /**
16+ * Time complexity: O ((n-m) * m log m)
17+ * where,
18+ * n = text length
19+ * m = pattern length
20+ *
21+ * @param text
22+ * @param pattern
23+ * @return
24+ */
1525 private static List <Integer > findAllAnagramsInTextNaive (String text , String pattern ) {
1626 List <Integer > indexes = new ArrayList <>();
17-
27+
1828 int textLen = text .length ();
1929 int patternLen = pattern .length ();
20-
30+
2131 char [] patternChars = pattern .toCharArray ();
2232 Arrays .sort (patternChars ); // takes O(m log m) time
2333 String patternSorted = String .valueOf (patternChars );
24-
34+
2535 String subText ;
2636 char [] subTextChars ;
2737 String subTextSorted ;
28-
38+
2939 for (int i = 0 ; i <= textLen - patternLen ; i ++) { // loops n-m number of times
30- subText = text .substring (i , i + patternLen );
40+ subText = text .substring (i , i + patternLen );
3141 subTextChars = subText .toCharArray ();
3242 Arrays .sort (subTextChars ); // sorts m number of characters, takes O(m log m)
3343 subTextSorted = String .valueOf (subTextChars );
34-
44+
3545 if (subTextSorted .equals (patternSorted )) { // compare m characters takes m time
3646 indexes .add (i );
3747 }
3848 }
3949 return indexes ;
4050 }
41-
51+
52+ /**
53+ * Time complexity: O(n). Completes within <a href="https://leetcode.com/submissions/detail/222911434/">7ms on
54+ * leetcode.</a>
55+ *
56+ * @param text
57+ * @param pattern
58+ * @return
59+ */
60+ private static List <Integer > findAllAnagramsInText (String text , String pattern ) {
61+ List <Integer > indices = new ArrayList <>();
62+
63+ int textLen = text .length ();
64+ int patternLen = pattern .length ();
65+
66+ int [] textCharCountInWindow = new int [26 ];
67+ int [] patternCharCount = new int [26 ];
68+
69+ for (int i = 0 ; i < patternLen ; i ++) {
70+ patternCharCount [pattern .charAt (i ) - 'a' ]++;
71+ }
72+
73+ for (int i = 0 ; i < textLen ; i ++) {
74+ textCharCountInWindow [text .charAt (i ) - 'a' ]++;
75+ if (i >= patternLen ) {
76+ textCharCountInWindow [text .charAt (i - patternLen ) - 'a' ]--;
77+ }
78+ if (Arrays .equals (textCharCountInWindow , patternCharCount )) { // loops 26 times no matter the text/pattern length
79+ indices .add (i - patternLen + 1 );
80+ }
81+ }
82+
83+ return indices ;
84+ }
85+
4286 public static void main (String [] args ) {
4387 // basic use cases
4488 System .out .println (findAllAnagramsInTextNaive ("cbaebabacd" , "abc" ));
4589 System .out .println (findAllAnagramsInTextNaive ("abab" , "ab" ));
46-
47- // corner cases
48- System .out .println (findAllAnagramsInTextNaive ("abab" , "" ));
90+ System .out .println (findAllAnagramsInTextNaive ("af" , "af" ));
91+ System .out .println (findAllAnagramsInTextNaive ("af" , "be" ));
92+
93+ // corner case
4994 System .out .println (findAllAnagramsInTextNaive ("" , "ab" ));
50- System .out .println (findAllAnagramsInTextNaive ("" , "" ));
95+
96+ System .out .println ("-----" );
97+
98+ // basic use cases
99+ System .out .println (findAllAnagramsInText ("cbaebabacd" , "abc" ));
100+ System .out .println (findAllAnagramsInText ("abab" , "ab" ));
101+ System .out .println (findAllAnagramsInText ("af" , "af" ));
102+ System .out .println (findAllAnagramsInText ("af" , "be" ));
103+
104+ // corner case
105+ System .out .println (findAllAnagramsInText ("" , "ab" ));
51106 }
52107}
0 commit comments