g2101_2200.s2157_groups_of_strings.Solution Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of leetcode-in-java21 Show documentation
Show all versions of leetcode-in-java21 Show documentation
Java-based LeetCode algorithm problem solutions, regularly updated
package g2101_2200.s2157_groups_of_strings;
// #Hard #String #Bit_Manipulation #Union_Find #2022_06_08_Time_451_ms_(93.86%)_Space_51_MB_(75.44%)
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* 2157 - Groups of Strings\.
*
* Hard
*
* You are given a **0-indexed** array of strings `words`. Each string consists of **lowercase English letters** only. No letter occurs more than once in any string of `words`.
*
* Two strings `s1` and `s2` are said to be **connected** if the set of letters of `s2` can be obtained from the set of letters of `s1` by any **one** of the following operations:
*
* * Adding exactly one letter to the set of the letters of `s1`.
* * Deleting exactly one letter from the set of the letters of `s1`.
* * Replacing exactly one letter from the set of the letters of `s1` with any letter, **including** itself.
*
* The array `words` can be divided into one or more non-intersecting **groups**. A string belongs to a group if any **one** of the following is true:
*
* * It is connected to **at least one** other string of the group.
* * It is the **only** string present in the group.
*
* Note that the strings in `words` should be grouped in such a manner that a string belonging to a group cannot be connected to a string present in any other group. It can be proved that such an arrangement is always unique.
*
* Return _an array_ `ans` _of size_ `2` _where:_
*
* * `ans[0]` _is the **maximum number** of groups_ `words` _can be divided into, and_
* * `ans[1]` _is the **size of the largest** group_.
*
* **Example 1:**
*
* **Input:** words = ["a","b","ab","cde"]
*
* **Output:** [2,3]
*
* **Explanation:**
*
* - words[0] can be used to obtain words[1] (by replacing 'a' with 'b'), and words[2] (by adding 'b'). So words[0] is connected to words[1] and words[2].
*
* - words[1] can be used to obtain words[0] (by replacing 'b' with 'a'), and words[2] (by adding 'a'). So words[1] is connected to words[0] and words[2].
*
* - words[2] can be used to obtain words[0] (by deleting 'b'), and words[1] (by deleting 'a'). So words[2] is connected to words[0] and words[1].
*
* - words[3] is not connected to any string in words.
*
* Thus, words can be divided into 2 groups ["a","b","ab"] and ["cde"]. The size of the largest group is 3.
*
* **Example 2:**
*
* **Input:** words = ["a","ab","abc"]
*
* **Output:** [1,3]
*
* **Explanation:**
*
* - words[0] is connected to words[1].
*
* - words[1] is connected to words[0] and words[2].
*
* - words[2] is connected to words[1].
*
* Since all strings are connected to each other, they should be grouped together.
*
* Thus, the size of the largest group is 3.
*
* **Constraints:**
*
* * 1 <= words.length <= 2 * 104
* * `1 <= words[i].length <= 26`
* * `words[i]` consists of lowercase English letters only.
* * No letter occurs more than once in `words[i]`.
**/
public class Solution {
public int[] groupStrings(String[] words) {
HashMap map = new HashMap<>();
for (String word : words) {
int bitmask = 0;
for (char ch : word.toCharArray()) {
bitmask |= (1 << (ch - 'a'));
}
map.put(bitmask, map.getOrDefault(bitmask, 0) + 1);
}
List keyset = new ArrayList<>();
for (Integer key : map.keySet()) {
keyset.add(key);
}
int totalGroups = 0;
int maxSize = 0;
for (Integer key : keyset) {
if (!map.containsKey(key)) {
continue;
}
totalGroups++;
int size = dfs(key, map);
maxSize = Math.max(size, maxSize);
}
return new int[] {totalGroups, maxSize};
}
private int dfs(Integer key, HashMap map) {
if (!map.containsKey(key)) {
return 0;
}
int size = map.get(key);
map.remove(key);
for (int i = 0; i < 26; i++) {
size += dfs((key ^ (1 << i)), map);
}
for (int i = 0; i < 26; i++) {
if ((key & (1 << i)) > 0) {
for (int j = 0; j < 26; j++) {
if ((key & (1 << j)) == 0) {
size += dfs((key ^ (1 << i) ^ (1 << j)), map);
}
}
}
}
return size;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy