프로그래머스 위장
from itertools import combinations
순열과 조합, 확률 등을 공부할 때 나오는 조합을 구현하는 방법이다. ['headgear', 'eyewear', 'shoes']에서 2개를 뽑는다면, 3C2로 3가지의 경우가 발생할 것이다. combinations(list, 2)로 간단하게 구현할 수 있다.
아래 그림에서처럼 tuple형태로 두 개씩 짝지어진 데이터들이 itertools 형태로 담긴다. list에 담아주어야 계속 사용할 수 있다. 그렇지 않으면 한번 iter가 돌면 사라지기 때문
모든 경우의 수를 세어 보는 문제이다.
PSEUDO
from itertools import combinations as cbs
def sol_1(clothes):
# make dict
vocab = dict()
for name, cat in clothes:
if cat not in vocab:
vocab[cat] = 1
else:
vocab[cat] += 1
ans = 0
for num in range(1, len(vocab)+1):
for com in list(cbs(vocab, num)):
temp = 1
for c in com:
temp *= vocab[c]
ans += temp
return ans
접근 방식을 조금 다르게 하면 아주 간단하게 문제가 풀린다. 프로그래밍의 문제라기 보다는 사고력 테스트...
PSEUDO
왜? 아래처럼 생각해보자. 오른쪽처럼 X(입지 않는 경우)를 추가해주면 자연스럽게 hat과 shirt만 입는 경우, shoes만 입는 경우 등을 포함할 수 있다. (A, D, X), (X, X, G) 등으로. 그리고 마지막에 -1을 해주는 것은 모두 X가 선택되는 경우를 제거해줘야 하기 때문이다. 너무나 간단하게 O(n)으로 풀 수 있다.
def sol_2(clothes):
vocab = dict()
for name, cat in clothes:
if cat in vocab:
vocab[cat] += 1
else: vocab[cat] = 1
ans = 1
for i in vocab.values():
ans *= (i+1)
return ans-1
Solution 1은 한 개의 케이스에서 시간초과가 발생, 소요시간만 얼핏봐도 두 코드의 시간 효율 차이가 크다는 것을 알 수 있다. 시간초과가 나면 다르게 접근할 수 있도록 머리를 써야겠다..