Programming/leetcode

49. Group Anagrams

홍열 2021. 1. 21. 16:01
728x90
  • 주어진 단어들 사이에서 출현빈도수가 같은것들만 묶어서 출력
  • 출력할때 순서는 길이와 사전순이다.

    Input:
    strs = ["eat","tea","tan","ate","nat","bat"] Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
    -> eat, tea, ate는 알파벳 횟수가 동일하므로 같은 군에 속한다. 
    -> output에는 길이와 사전순 정렬이 필요하다.


  • 1차 아이디어
    collection을 이용해서 빈도수를 세고, collection.Counter끼리 비교
    -> 시간 초과
    result = []
    for str in strs:
        if not result:
            result.append([str])
        else:
            flag = False
            for items in result:
                if collections.Counter(items[0]) == collections.Counter(str):
                    items.append(str)
                    flag = True
                    break
            if not flag:
                result.append([str])


    for item in result:
        item.sort(key=lambda x:x)
    result.sort(key=lambda x:len(x))
    return result

 

  • 2차 아이디어
    단어별 아스키 코드값의 총합을 구해서 집합을 만든다. 
    -> 아스키 코드 총합이 같은것끼리 묶이는 현상 발생 (["duh","ill"])
    result = dict()
    for str in strs:
        cur = 0
        for item in str:
            cur += ord(item)
        if cur in result.keys():
            result[cur].append(str)
        else:
            result[cur] = [str]
    result = [item for item in result.values()]
    for item in result:
        item.sort(key=lambda x:x)
    result.sort(key=lambda x:len(x))
    return result

 

  • 3차 아이디어
    시간 초과가 나는 이유를 자세히 보면 배열이 여러개 들어오고, 그 배열을 for문으로 두번 돌리기때문이다 
    이를 해결하기 위해서는 다른 아이디어가 필요하다.

    Anagram을 처음으로 돌아가보자. 
    각 문자열에 같은 문자가 몇번 나왔는지만 비교하면된다. 
    -> 비교 횟수를 구하지말고, 차라리 문자열 자체를 정렬하자. 
    -> "ate", "tea", "eat"를 사전순으로 정렬하면 모두 "aet"가 된다. 
    -> 이것을 key로 하고, 값을 구하면 된다.
# default dict사용...초기값을 지정해줄 필요가 없어 편하다. 
result = collections.defaultdict(list)

for s in strs:
	#문자열을 정렬하면, list가 나오는데 join함수를 이용해서 문자열로 만들자.
    result[''.join(sorted(s))].append(s)

 

  • 다른 사람 풀이중 신기했던 것
    내가 생각한 아스키 코드 이용하는 것인데, 중요한것은 dict의 키 값에 tuple 자체가 들어갈 수 있다는 것이었다 
    이 방법을 생각했다면 2번째 풀이로도 풀수 있겠다는 생각이 들었다.
    for s in strs:
        count = [0] * 26
        for c in s:
            count[ord(c) - ord('a')] += 1
        ans[tuple(count)].append(s)

    return ans.values()