문제 링크
The problem link : Sherlock and Anagrams
문제 요약
n개의 문자열이 주어졌을때, 각 문자열마다 애너그램을 통해 서로 같은 문자열을 만들 수 있는 쌍의 개수를 찾으세요.
(* 애너그램 : 재배열을 했을때 다른 뜻의 문자를 만듦)
애너그램의 예시는 다음과 같습니다.
s = mom
[m,m] [mo,om] -> 2개의 정답
문제 풀이
핵심 코드는 다음과 같습니다.
public static void add(HashMap<String,Integer> hm, String s){ // 3
char a[] = s.toCharArray();
Arrays.sort(a); // (1)
ns = new String(a);
hm.putIfAbsent(ns,0); // (2)
hm.put(s, hm.get(ns)+1); // (3)
}
public static int sherlockAndAnagrams(String s) {
HashMap <String, Integer> hm = new HashMap<>(); // 1
int ans = 0;
for(int i=0; i<s.length(); i++){
for(int j=i+1; j<=s.length(); j++){
add(hm, s.substring(i,j)); // 2
}
}
for(int k:hm.values()){ // 4
ans += (k*(k-1))/2;
}
return ans;
}
HashMap
으로 변수를 생성합니다. 애너그램으로 같은 문자열을 만들 수 있는 문자열 String과 그것의 쌍의 개수를 저장한 Integer로HashMap
을 생성합니다.- 2중 for문을 통해 문자열 s의
i
번째에서j-1
번째까지의 문자들 중 정답의 개수를 찾기위해 add라는 메서드로 탐색을 시작합니다. - (1) 문자열
s
를 문자 타입으로 쪼개서 저장한 뒤, 오름차순으로 정렬합니다. 그런 다음 정렬된 문자 타입의 배열을 새로운 문자열ns
로 만듭니다.
(2) 오름차순으로 정렬된 새로운 문자열ns
가hm
에 없을 경우, 0의 개수로 새로이 저장해줍니다.
여기서 사용되는putIfAbsent
는 key값이 존재할경우 key값을 반환해주고, 그렇지 않을 경우 key와 value 쌍을 HashMap에 저장해주고 null을 반환합니다.
(3) 오름차순으로 정렬된 새로운 문자열ns
를hm
에 (기존에 존재했던 value의) 1을 더하여 저장해줍니다. hm
에서 모든 value의 값을 (x*(x-1))/2 하여 더해줍니다.
이렇게하는 이유는 아래의 예시와 같습니다.
s = kkkkkk
여기서 'k' 문자로 정답이 가능한 개수는 15개 입니다.
1. 첫 번째 k / 나머지 kkkkk -> 5개
2. 두 번째 k / 나머지 kkkk -> 4개 (첫 번째 k와는 이미 쌍이 이루어졌으므로 포함X)
3. 세 번째 k / 나머지 kkk -> 3개 (")
4. 네 번째 k / 나머지 kk -> 2개 (")
5. 다섯번 째 k / 나머지 k -> 1개 (")
= 총합 15개
그런 다음 합산된 정답을 출력해줍니다.
시간 복잡도
O(n2) 입니다.
HashMap에서 value로 값을 찾는건 O(n)이지만, 중간에 2중 for문을 돌리는 부분이 있으므로 위 코드의 시간복잡도는 O(n2) 입니다.
'🖥️ CS > SW Expert 외의 Algorithms' 카테고리의 다른 글
HackerRank : Count Triplets (0) | 2023.02.19 |
---|---|
HackerRank : Frequency Queries (0) | 2023.02.15 |
LeetCode 771. Jewels and Stones (Java) (1) | 2023.01.10 |
HackerRank : Largest Rectangle (0) | 2022.11.25 |
HackerRank : A Tale of Two Stacks (0) | 2022.11.23 |