[Algorithm] Lv1. 숫자 짝꿍((programmers)
Intro
프로그래머스 Lv1. 문제인 숫자 짝꿍 문제에 대해 풀이하고자 합니다.
문제

입출력 예시

🥸 나의 접근 방법(오답)
- x_dict, y_dict에 for 반복문을 사용하여 2개의 딕셔너리를 제작한다.
- dict.get()을 사용하여 키 값이 존재하지 않을 경우 1을 넣어주고, 존재하는 경우 증감처리.
- for 반복문을 사용하여 x_dict.keys() 를 통해 key를 하나씩 꺼내어 key가 y_dict에 존재하는 지 파악
- 존재하는 경우 → 해당 문자열 * 공통횟수(min을 사용)의 문자열을 answer에 증감하여 처리. (문제에서 제시한 0만 존재하는 경우는 “0”으로 출력해야 하기에 여기서 처리하였음.)
- 존재하지 않는 경우 → 별도의 if문을 사용하여 ‘-1’ 문자열을 return.
- 문제점(테스트 결과: 6~15 실패)
- solution(100, 100) 으로 진행했을 때 0에 대한 처리가 되지 않았음. (출력이 100이 되야 하는데 위 접근방법으로 진행 시 10이 출력 되었음.)
- 문제 해결과정
- 0만 존재하는 경우를 처리하는 부분을 별도로 분리하였음. (분기가 많아짐에 따라 코드가 복잡해지는 현상 해결)
- 변경 전 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14
for i in x_dict.keys(): # key가 y_dict에 존재할 경우 & 0이 아닌 경우 if i in y_dict and i != '0': # min 사용 이유 : x_dict, y_dict에서 적은 횟수가 공통횟수이기 때문에 사용. answer += str(str(i) * min(x_dict[i], y_dict[i])) # 존재하면서 & 0인 경우 (0인 경우는 1번만 더해야 함.) elif i in y_dict and i == '0': answer += str(i) # 내림차순 정렬하기. answer = ''.join(sorted(list(answer),reverse=True)) # key가 y_dict에 존재하지 않을 경우 -1 if answer == '': answer = '-1'
- 변경 후 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
for x in x_dict.keys(): if x in y_dict: x = str(x) iternum = min(x_dict[x], y_dict[x]) answer += x * iternum # 내림차순 정렬 answer = "".join(sorted(list(answer), reverse=True)) # # key가 y_dict에 존재하지 않을 경우 -1 if answer == '': return '-1' elif len(answer) == answer.count("0"): return '0' else: return answer
🤩 다른 접근 방법(정답, 블로그 참고)
- 기존 풀이는 X, Y에 있는 값들만 dict에 추가했지만, 해당 풀이는 0~9까지의 모든 키에 0이라는 값을 넣어서 딕셔너리를 2개 제작함.
- X, Y 원소들을 하나씩 dict[key] 문법을 사용하여 증감처리.
- 정렬을 사용하지 않고, range(9,-1,-1)을 사용하여 문제에서 제시하는 가장 큰 정수를 만든다.
❌ 오답 코드(테스트 결과 : 6~15 실패한 코드)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def solution(X, Y):
x_dict = {}
y_dict = {}
for i in X:
# 존재하지 않을 경우 1을 넣어줌.
if x_dict.get(i) == None:
x_dict[i] = 1
else:
# 존재할 경우 증감처리
x_dict[i] += 1
for i in Y:
# 존재하지 않을 경우 1을 넣어줌.
if y_dict.get(i) == None:
y_dict[i] = 1
else:
# 존재할 경우 증감처리
y_dict[i] += 1
# print(x_dict.keys()
for i in x_dict.keys():
# key가 y_dict에 존재할 경우 & 0이 아닌 경우
if i in y_dict and i != '0':
# min 사용 이유 : x_dict, y_dict에서 적은 횟수가 공통횟수이기 때문에 사용.
answer += str(str(i) * min(x_dict[i], y_dict[i]))
# 존재하면서 & 0인 경우 (0인 경우는 1번만 더해야 함.)
elif i in y_dict and i == '0':
answer += str(i)
# 내림차순 정렬하기.
answer = ''.join(sorted(list(answer),reverse=True))
# key가 y_dict에 존재하지 않을 경우 -1
if answer == '':
answer = '-1'
return answer
⭕️ 정답 코드1(내가 생각한 풀이)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def solution(X, Y):
x_dict = {}
y_dict = {}
answer = ''
for i in X:
# 존재하지 않을 경우 1을 넣어줌.
if x_dict.get(i) == None:
x_dict[i] = 1
else:
# 존재할 경우 증감처리
x_dict[i] += 1
for i in Y:
# 존재하지 않을 경우 1을 넣어줌.
if y_dict.get(i) == None:
y_dict[i] = 1
else:
# 존재할 경우 증감처리
y_dict[i] += 1
for x in x_dict.keys():
if x in y_dict:
x = str(x)
iternum = min(x_dict[x], y_dict[x])
answer += x * iternum
answer = "".join(sorted(list(answer), reverse=True))
# # key가 y_dict에 존재하지 않을 경우 -1
if answer == '':
return '-1'
elif len(answer) == answer.count("0"):
return '0'
else:
return answer
⭕️ 정답 코드2(블로그 풀이)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def solution(X, Y):
answer = ''
x_dict = {str(i) : 0 for i in range(10)}
y_dict = {str(i) : 0 for i in range(10)}
for x in X:
x_dict[x] += 1
for y in Y:
y_dict[y] += 1
# 공통된 정수 제작
for k in range(9, -1, -1):
k = str(k)
iternum = min(x_dict[k], y_dict[k]) # x_dict, y_dict에서 적은 횟수가 공통횟수이기 때문에 사용함.
answer += k * iternum
if answer == '': # 공백에 대한 처리(중복된 숫자가 없는 경우)
return "-1"
elif len(answer) == answer.count('0'): # 0에 대한 처리
return '0'
else:
return answer
회고
- 딕셔너리 문법에서 dict[key], dict.get() 의 차이를 기억하자.
- 전자(dict[key])의 경우는 key가 없는 경우 KeyError가 발생하지만, 후자(get)는 None이 출력된다. 또한 get(dict, “디폴트 값”)을 사용할 수 있다.
- 분기를 할 때 굳이 한 번에 and 절을 추가하려 하지 말고, 다른 부분에서 처리할 수 있는 방법도 생각해보자.
- 다른 사람 풀이를 보면, 정렬을 사용하는 대신 문제에서 k범위(0≤K≤9)를 제시한 것을 이용하였다. 문제를 더 확인하고 범위를 이용하도록 풀어보자.