|
| 1 | +/** |
| 2 | + * @param {string[]} strs |
| 3 | + * @return {string[][]} |
| 4 | + */ |
| 5 | +/* |
| 6 | +주어진 문자열 배열 strs에서, |
| 7 | +서로 아나그램(anagram) 관계인 문자열들을 묶어 그룹으로 반환하는 문제이다. |
| 8 | +
|
| 9 | +아나그램이란? |
| 10 | + - 문자열의 문자들을 재배열하여 서로 같은 구성을 만들 수 있는 문자열을 의미한다. |
| 11 | + - 예: "eat", "tea", "ate"는 같은 아나그램 그룹에 속함. |
| 12 | +
|
| 13 | +목표: |
| 14 | + - strs 내 모든 문자열을 아나그램끼리 묶은 그룹들의 배열로 반환한다. |
| 15 | + - 그룹의 순서나, 그룹 내부 문자열의 순서는 중요하지 않다. |
| 16 | +
|
| 17 | +입력 형식 : |
| 18 | + - strs: 문자열 배열 |
| 19 | + - 1 <= strs.length <= 10,000 |
| 20 | + - 0 <= strs[i].length <= 100 |
| 21 | + - strs[i]는 모두 소문자 영어 알파벳으로 구성됨 |
| 22 | +
|
| 23 | +출력 형식 : |
| 24 | + - 아나그램끼리 묶인 그룹들의 배열 (2차원 배열) |
| 25 | +
|
| 26 | +예시 : |
| 27 | +
|
| 28 | + Example 1 |
| 29 | + 입력 : ["eat","tea","tan","ate","nat","bat"] |
| 30 | + 출력 : [["bat"], ["nat","tan"], ["ate","eat","tea"]] |
| 31 | + 설명 : |
| 32 | + - "eat", "tea", "ate"는 문자 구성이 동일하므로 같은 그룹 |
| 33 | + - "tan", "nat"도 서로 아나그램이므로 같은 그룹 |
| 34 | + - "bat"는 다른 어떤 문자열로도 아나그램을 만들 수 없으므로 단독 그룹 |
| 35 | +
|
| 36 | + Example 2 |
| 37 | + 입력 : [""] |
| 38 | + 출력 : [[""]] |
| 39 | + 설명 : |
| 40 | + - 빈 문자열도 하나의 문자열로 취급되며, 자신과 함께 단일 그룹 생성 |
| 41 | +
|
| 42 | + Example 3 |
| 43 | + 입력 : ["a"] |
| 44 | + 출력 : [["a"]] |
| 45 | + 설명 : |
| 46 | + - 단일 문자 하나만 있으므로 그대로 그룹화됨 |
| 47 | +*/ |
| 48 | +var groupAnagrams = function (strs) { |
| 49 | + |
| 50 | + const processed = new Set(); |
| 51 | + const result = []; |
| 52 | + |
| 53 | + for (let i = 0; i < strs.length; i++) { |
| 54 | + |
| 55 | + const base_word = strs[i]; |
| 56 | + if (processed.has(base_word)) continue; |
| 57 | + |
| 58 | + const baseMap = new Map(); |
| 59 | + |
| 60 | + for (const base_word_char of base_word) { |
| 61 | + if (baseMap.has(base_word_char)) { |
| 62 | + let base_word_char_count = baseMap.get(base_word_char); |
| 63 | + |
| 64 | + base_word_char_count++; |
| 65 | + baseMap.set(base_word_char, base_word_char_count) |
| 66 | + } else { |
| 67 | + baseMap.set(base_word_char, 1) |
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + const group = [base_word]; |
| 72 | + processed.add(base_word); |
| 73 | + |
| 74 | + for (let j = i + 1; j < strs.length; j++) { |
| 75 | + |
| 76 | + const candidate_word = strs[j]; |
| 77 | + |
| 78 | + if (processed.has(candidate_word)) continue; |
| 79 | + |
| 80 | + const compareMap = new Map([...baseMap]); |
| 81 | + |
| 82 | + for (const candidate_word_char of candidate_word) { |
| 83 | + if (compareMap.has(candidate_word_char)) { |
| 84 | + |
| 85 | + let candidate_word_char_count = compareMap.get(candidate_word_char) |
| 86 | + candidate_word_char_count--; |
| 87 | + |
| 88 | + if (candidate_word_char_count === 0) { |
| 89 | + compareMap.delete(candidate_word_char) |
| 90 | + } else if (candidate_word_char_count > 0) { |
| 91 | + compareMap.set(candidate_word_char, candidate_word_char_count) |
| 92 | + } |
| 93 | + } |
| 94 | + } |
| 95 | + |
| 96 | + //최종 리턴 |
| 97 | + if (compareMap.size == 0) { |
| 98 | + processed.add(candidate_word); |
| 99 | + group.push(candidate_word); |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + result.push(group); |
| 104 | + |
| 105 | + } |
| 106 | + |
| 107 | + return result; |
| 108 | +}; |
| 109 | + |
| 110 | +console.log(groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"])) |
| 111 | +console.log(groupAnagrams([""])) |
| 112 | +console.log(groupAnagrams(["a"])) |
| 113 | + |
| 114 | + |
0 commit comments