link: https://programmers.co.kr/learn/courses/30/lessons/42746
0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.
0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.
numbers의 길이는 1 이상 100,000 이하입니다.
numbers의 원소는 0 이상 1,000 이하입니다.
정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.
def solution(numbers):
numbers.sort(key=lambda x:(-x%(10**(int(len(str(x)))))), reverse = False)
answer = ''
for x in numbers:
answer += str(x)
return answer
# numbers = [6,10,2]
numbers = [3, 30, 34, 5, 9]
print(solution(numbers))
위 코드에서 오류를 찾을 수 있다. 입력값을 [6,10,2] 로 하였을 때에는 올바른 값을 구 할 수 있었다. 하지만 [3, 30, 34, 5, 9]를 입력하였을 때 구해야하는 값(9534330)이 나오지 않고 9533430이 나왔다. 즉 3이 34보다 앞서도록 정렬하였기 때문이다. 이 코드의 문제를 해결하기위해 숫자들을 비교하여 다시 정렬하도록 풀어봤다.
import functools
def solution(numbers):
numbers.sort(key=functools.cmp_to_key(compare), reverse = True)
answer = ''
for x in numbers:
answer += str(x)
return answer
def compare(a,b):
t1 = str(a) + str(b)
t2 = str(b) + str(a)
if int(t1) > int(t2): return 1
elif int(t1) < int(t2): return -1
else: return 0
# numbers = [6,10,2]
numbers = [3, 30, 34, 5, 9]
print(solution(numbers))
최우선적으로 이 문제는 원하는 답을 구하기위해 숫자들을 '정렬' 해야한다. 정렬기준은 숫자가 큰 순서가 아닌 나열 했을때 가장 크게 조합이 되는 수 이다. 즉 3 과 30 이 있다고 가정하면 우리는 3, 30 순으로 나열 해야한다.
'compare'
이 function을 보면 두가지 수를 비교하여 어떤 수를 기준으로 정렬해야할지 정해준다. 3 과 30을 비교한다고 가정하자. 우리는 3+30(330)과 30+3(303)을 비교하여 330이 303보다 크다는 것을 알 수 있다. string으로 바꾼 두 수를 더하여 비교를 했을때 더 t1이 크다면 1을 t2가 더 크다면 -1을, 그리고 같으면 0을 반환하는 방식으로 순서를 정해줄 함수를 만든다.
def solution(numbers):
numbers = list(map(str, numbers))
numbers.sort(key=lambda x: x*3, reverse=True)
return str(int(''.join(numbers)))
출처: 프로그래머스 가장 큰 수 'Best' 풀이
정수가 아닌 문자(string) x에 * 3을 하여 가장 앞에 숫자부터 숫자를 비교하여 누가 더 큰지 작은지를 구분해 주는 풀이를 사용했다.
너무 간결하고 단순해 보이지만 절대로 쉽게 생각해 낼 수 있는 코드가 아니다.