Skip to content

Commit be4e5ab

Browse files
committed
Update group anagrams problem
1 parent 4b283b2 commit be4e5ab

File tree

4 files changed

+136
-53
lines changed

4 files changed

+136
-53
lines changed

src/java1/algorithms/strings/groupAnagrams/GroupAnagrams.java

+33-32
Original file line numberDiff line numberDiff line change
@@ -3,54 +3,55 @@
33
import java.util.*;
44

55
public class GroupAnagrams {
6+
7+
//HashMap and char array:- TC:O(n * m) SC:O(n)
8+
private static List<List<String>> groupAnagram1(String[] strs) {
9+
Map<String, List<String>> groupAnagramMap = new HashMap<>();
10+
11+
for(String str: strs) {
12+
int[] charsCount = new int[26];
13+
14+
for(char ch: str.toCharArray()) {
15+
charsCount[ch - 'a']++;
16+
}
17+
18+
StringBuilder sb = new StringBuilder();
19+
for(int num: charsCount) {
20+
sb.append("*");
21+
sb.append(num);
22+
}
23+
24+
String key = sb.toString();
25+
groupAnagramMap.putIfAbsent(key, new ArrayList<>());
26+
groupAnagramMap.get(key).add(str);
27+
}
28+
return new ArrayList<>(groupAnagramMap.values());
29+
}
30+
631
//HashMap using sorted strings:- TC:O(n * mlogn) SC:O(n)
7-
private static List<List<String>> groupAnagram(String[] strs) {
8-
Map<String, List<String>> hashMap = new HashMap<>();
32+
private static List<List<String>> groupAnagram2(String[] strs) {
33+
Map<String, List<String>> groupAnagramMap = new HashMap<>();
934

1035
for(String str: strs) {
1136
char[] chars = str.toCharArray();
1237
Arrays.sort(chars);
1338
String sortedStr = new String(chars);
14-
if(!hashMap.containsKey(sortedStr)) {
15-
hashMap.put(sortedStr, new ArrayList<>());
39+
if(!groupAnagramMap.containsKey(sortedStr)) {
40+
groupAnagramMap.put(sortedStr, new ArrayList<>());
1641
}
17-
hashMap.get(sortedStr).add(str);
42+
groupAnagramMap.get(sortedStr).add(str);
1843
}
1944

20-
return new ArrayList<>(hashMap.values());
21-
}
22-
23-
//HashMap and char array:- TC:O(n * m) SC:O(n)
24-
private static List<List<String>> groupAnagram1(String[] strs) {
25-
Map<String, List<String>> hashMap = new HashMap<>();
26-
27-
for(String str: strs) {
28-
int[] charsCount = new int[26];
29-
30-
for(char ch: str.toCharArray()) {
31-
charsCount[ch - 'a']++;
32-
}
33-
34-
StringBuilder sb = new StringBuilder();
35-
for(int i=0; i< 26; i++) {
36-
sb.append("*");
37-
sb.append(charsCount[i]);
38-
}
39-
40-
String key = sb.toString();
41-
hashMap.putIfAbsent(key, new ArrayList<>());
42-
hashMap.get(key).add(str);
43-
}
44-
return new ArrayList<>(hashMap.values());
45+
return new ArrayList<>(groupAnagramMap.values());
4546
}
4647

4748
public static void main(String[] args) {
4849
String[] strs1 = {"eat","tea","tan","ate","nat","bat"};
49-
System.out.println(groupAnagram(strs1));
5050
System.out.println(groupAnagram1(strs1));
51+
System.out.println(groupAnagram2(strs1));
5152

5253
String[] strs2 = {"hello"};
53-
System.out.println(groupAnagram(strs2));
5454
System.out.println(groupAnagram1(strs2));
55+
System.out.println(groupAnagram2(strs2));
5556
}
5657
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
**Description:**
2+
Given an array of strings strs, group the anagrams together. You can return the answer in any order.
3+
4+
**Note:**An Anagram is defined as a word or phrase formed by rearranging the letters of a different word or phrase, using all the original letters exactly once.
5+
6+
### Examples
7+
Example 1:
8+
Input: strs = ["eat","tea","tan","ate","nat","bat"]
9+
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
10+
11+
Example 2:
12+
Input: strs = ["hello"]
13+
Output: [["hello"]]
14+
15+
Example 3:
16+
Input: strs = [""]
17+
Output: [[""]]
18+
19+
**Algorithmic Steps**
20+
This problem is solved with the combination of **frequency counting** approach using an array and store anagrams in a map. The algorithmic approach can be summarized as follows:
21+
22+
1. Initialize an empty object(`groupAnagramMap`) to store list of anagrams.
23+
24+
2. Iterate over the list of given input strings array to find anagrams.
25+
26+
3. Create a character frequency array(`charsCount`) with respect to 26 letters of alphabetics. Each value is assigned with zero by default.
27+
28+
4. Iterate over the each character/letter of a string and update the character frequency.
29+
30+
5. Calculate a unique hash key with the combination of the character frequency and prefix symbol.
31+
32+
6. If the key already exists in the anagram object, append the new anagram to the list. Otherwise create a new anagram array for the given key.
33+
34+
7. Repeat steps 3-6 until there are no strings available.
35+
36+
8. Return group of anagrams in an array format.
37+
38+
**Time and Space complexity:**
39+
This algorithm takes a time complexity of `O(m * n)`, where `m` represents the number of strings and `n` represents length of each string. This is because we are traversing each string in the given list of strings.
40+
41+
Also, it requires space complexity of `O(m * n)` due to object/map data structure which store list of an arrays.
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,42 @@
1-
//Using object and sort:- TC: O(m * n log n) OC: O(m * n)
2-
function groupAnagram(strs) {
1+
//Character count:- TC:O(m * n) OC: O(m * n)
2+
function groupAnagram1(strs) {
33
let groupAnagramObj = {};
44

55
for(let str of strs) {
6-
const sortedString = str.split("").sort().join("");
7-
if(groupAnagramObj[sortedString]) {
8-
groupAnagramObj[sortedString].push(str);
6+
const charFrequency = new Array(26).fill(0);
7+
for(let i=0; i<str.length; i++) {
8+
const charIndex = str.charCodeAt(i) - 97;
9+
charFrequency[charIndex]++;
10+
}
11+
const key = charFrequency.join("#");
12+
if(groupAnagramObj[key]) {
13+
groupAnagramObj[key].push(str);
914
} else {
10-
groupAnagramObj[sortedString] = [str];
15+
groupAnagramObj[key] = [str];
1116
}
1217
}
1318
return Object.values(groupAnagramObj);
1419
}
1520

16-
//Character count:- TC:O(m * n) OC: O(n)
17-
function groupAnagram1(strs) {
21+
//Using object and sort:- TC: O(m * n log n) OC: O(m * n)
22+
function groupAnagram2(strs) {
1823
let groupAnagramObj = {};
1924

2025
for(let str of strs) {
21-
const chars = new Array(26).fill(0);
22-
for(let i=0; i<str.length; i++) {
23-
const charIndex = str.charCodeAt(i) - 97;
24-
chars[charIndex]++;
25-
}
26-
const key = chars.join("#");
27-
if(groupAnagramObj[key]) {
28-
groupAnagramObj[key].push(str);
26+
const sortedString = str.split("").sort().join("");
27+
if(groupAnagramObj[sortedString]) {
28+
groupAnagramObj[sortedString].push(str);
2929
} else {
30-
groupAnagramObj[key] = [str];
30+
groupAnagramObj[sortedString] = [str];
3131
}
3232
}
33-
return Array.from(Object.values(groupAnagramObj));
33+
return Object.values(groupAnagramObj);
3434
}
3535

3636
let strs1 = ["eat","tea","tan","ate","nat","bat"];
37-
console.log(groupAnagram(strs1));
3837
console.log(groupAnagram1(strs1));
38+
console.log(groupAnagram2(strs1));
3939

4040
let strs2 = ["hello"];
41-
console.log(groupAnagram(strs2));
42-
console.log(groupAnagram1(strs2));
41+
console.log(groupAnagram1(strs2));
42+
console.log(groupAnagram2(strs2));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
**Description:**
2+
Given an array of strings strs, group the anagrams together. You can return the answer in any order.
3+
4+
**Note:**An Anagram is defined as a word or phrase formed by rearranging the letters of a different word or phrase, using all the original letters exactly once.
5+
6+
### Examples
7+
Example 1:
8+
Input: strs = ["eat","tea","tan","ate","nat","bat"]
9+
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
10+
11+
Example 2:
12+
Input: strs = ["hello"]
13+
Output: [["hello"]]
14+
15+
Example 3:
16+
Input: strs = [""]
17+
Output: [[""]]
18+
19+
**Algorithmic Steps**
20+
This problem is solved with the combination of **frequency counting** approach using an array and store anagrams in an object/map. The algorithmic approach can be summarized as follows:
21+
22+
1. Initialize an empty object(`groupAnagramObj`) to store list of anagrams.
23+
24+
2. Iterate over the list of given input strings array to find anagrams.
25+
26+
3. Create a character frequency array(`charFrequency`) with respect to 26 letters of alphabetics. Each value is assigned with zero.
27+
28+
4. Iterate over the each character/letter of a string and update the character frequency.
29+
30+
5. Calculate a unique hash key based on the character frequency.
31+
32+
6. If the key already exists in the anagram object, append the new anagram to the list. Otherwise create a new anagram array for the given key.
33+
34+
7. Repeat steps 3-6 until there are no strings available.
35+
36+
8. Return group of anagrams in an array format.
37+
38+
**Time and Space complexity:**
39+
This algorithm takes a time complexity of `O(m * n)`, where `m` represents the number of strings and `n` represents length of each string. This is because we are traversing each string in the given list of strings.
40+
41+
Also, it requires space complexity of `O(m * n)` due to object/map data structure which store list of an arrays.

0 commit comments

Comments
 (0)