6
6
7
7
/**
8
8
* Leetcode Problem: https://leetcode.com/problems/find-all-anagrams-in-a-string/
9
- *
9
+ *
10
10
* @author rampatra
11
11
* @since 2019-04-13
12
12
*/
13
13
public class AnagramsInString {
14
14
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
+ */
15
25
private static List <Integer > findAllAnagramsInTextNaive (String text , String pattern ) {
16
26
List <Integer > indexes = new ArrayList <>();
17
-
27
+
18
28
int textLen = text .length ();
19
29
int patternLen = pattern .length ();
20
-
30
+
21
31
char [] patternChars = pattern .toCharArray ();
22
32
Arrays .sort (patternChars ); // takes O(m log m) time
23
33
String patternSorted = String .valueOf (patternChars );
24
-
34
+
25
35
String subText ;
26
36
char [] subTextChars ;
27
37
String subTextSorted ;
28
-
38
+
29
39
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 );
31
41
subTextChars = subText .toCharArray ();
32
42
Arrays .sort (subTextChars ); // sorts m number of characters, takes O(m log m)
33
43
subTextSorted = String .valueOf (subTextChars );
34
-
44
+
35
45
if (subTextSorted .equals (patternSorted )) { // compare m characters takes m time
36
46
indexes .add (i );
37
47
}
38
48
}
39
49
return indexes ;
40
50
}
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
+
42
86
public static void main (String [] args ) {
43
87
// basic use cases
44
88
System .out .println (findAllAnagramsInTextNaive ("cbaebabacd" , "abc" ));
45
89
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
49
94
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" ));
51
106
}
52
107
}
0 commit comments