Problem
String[] strs
값이 주어지면 Anagrams 을 이루는 단어들을 한 리스트로 묶어서 출력하는 문제입니다.
Anagrams 이란 문자의 순서를 바꾸어서 만들 수 있는 다른 문자를 말하며
간단히 생각하면 같은 숫자의 문자들로 이루어진 String
들을 하나로 묶으면 됩니다.
주어지는 값은 모두 소문자이며 출력 순서는 상관 없다는 조건이 있습니다.
Solution
Hash 로 문제를 해결할 수 있습니다.
주어진 문자열이 소문자 알파벳만으로 이루어졌다는 사실을 통해서 해시를 구현할 수 있습니다.
길이 26 의 int
배열을 선언한 뒤에 알파벳 숫자만큼 카운팅 합니다.
예를 들어 bacc
라는 문자열을 받았을 때 이걸 keyArray
로 변환한다면
[1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
이런 문자열이 됩니다.
accb
도 변환한다면 위와 같은 문자열이 됩니다.
Arrays.toString(int[] arr)
을 통해 배열을 통째로 String
으로 변환할 수 있습니다.
내부적으로 for
문과 StringBuilder
를 사용하기 때문에 시간복잡도는 O(N * K)
가 됩니다.
두 번째 솔루션은 다른 사람들의 Submission Code 를 참고했습니다.
두번째 솔루션과 같은 해시지만 배열 String
을 그대로 키 값으로 사용했던 것과 달리 Long
값을 사용합니다.
26 개의 소수값을 배열에 미리 넣어둔 뒤 알파벳의 갯수만큼 hashKey
값에 곱해줍니다.
이와 같은 풀이가 가능한 이유는 소수의 곱이라 다른 Anagrams 값과 중복될 일이 전혀 없기 때문입니다.
시간복잡도는 동일하게 O(N * K)
지만 Array to String
과정이 없기 때문에 세번째 솔루션이 미세하게 더 빠릅니다.
Java Code
// 1. 배열 자체를 String 으로 만들어서 키값으로 사용
// k 값이 작아서 그런건지 키값 String 길이가 길어서 그런건지 소트보다 속도는 느림
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for (String str : strs) {
int[] count = new int[26];
for (char c : str.toCharArray()) count[c - 'a']++;
String key = Arrays.toString(count);
if (!map.containsKey(key)) {
map.put(key, new LinkedList<>());
}
map.get(key).add(str);
}
return new ArrayList<>(map.values());
}
}
// 2. 소수값을 이용하여 hash key 값을 만듬
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
int[] primes = {2, 3, 5, 7, 11, 13, 17, 19,
23, 29, 31, 37, 41, 43, 47, 53,
59, 61, 67, 71, 73, 79, 83, 89,
97, 101};
Map<Long, List<String>> map = new HashMap<>();
for (String str : strs) {
long hashKey = 1;
for (char c : str.toCharArray()) {
hashKey *= (long) primes[c - 'a'];
}
if (!map.containsKey(hashKey)) {
map.put(hashKey, new LinkedList<>());
}
map.get(hashKey).add(str);
}
return new LinkedList<>(map.values());
}
}
'알고리즘 문제 > LeetCode' 카테고리의 다른 글
[LeetCode Medium] Odd Even Linked List (Java) (0) | 2021.01.03 |
---|---|
[LeetCode Medium] Find the Duplicate Number (Java) (0) | 2021.01.02 |
[LeetCode Medium] Rotate Image (Java) (0) | 2021.01.01 |
[LeetCode Medium] Product of Array Except Self (Java) (0) | 2020.12.31 |
[LeetCode Medium] Kth Smallest Element in a BST (Java) (0) | 2020.12.31 |