STUDY/Algorithm

[프로그래머스] LEVEL2 가장큰수, python3, 정렬

sinawi95 2019. 11. 6. 10:52
728x90

1차 시도

from itertools import permutations
def solution(numbers):
    answer = ''
    ## permutation of elements of numbers
    numbers=list(map(str,numbers))
    tmp=list(map(''.join, permutations(numbers)))
    answer=max(tmp)
    return answer

논리는 맞는거 같은데 permutation할때 시간이 오래 걸리는듯 하다.


2차시도

def solution(numbers):
    answer = ''
    tmp_nums=[]
    max_len=len(str(max(numbers)))
    for num in numbers:
        length=0
        len_num=len(str(num))
        tmp=[len_num]
        str_num=str(num)
        for i in range(max_len):
            try:
                tmp.append(str_num[i])
            except:
                tmp.append(str_num[0])
        tmp_nums.append(tmp)
    #print(tmp_nums)
    if max_len==4:
        tmp_nums=sorted(tmp_nums,key= lambda x: (-int(x[1]),-int(x[2]),-int(x[3]),-int(x[4]),x[0]))
    elif max_len==3:
        tmp_nums=sorted(tmp_nums,key= lambda x: (-int(x[1]),-int(x[2]),-int(x[3]),x[0]))
    elif max_len==2:
        tmp_nums=sorted(tmp_nums,key= lambda x: (-int(x[1]),-int(x[2]),x[0]))
    elif max_len==1:
        tmp_nums=sorted(tmp_nums,key= lambda x: (-int(x[1]),x[0]))
    else:
        pass
    #print(tmp_nums)
    for list_nums in tmp_nums:
        list_len=list_nums[0]
        for j in range(list_len):
            answer+=list_nums[j+1]
            
    return answer

뭔가 길게했는데 몇개는 답이 안맞나보다. 테스트케이스를 더 구해봐야할듯


자리수 맞춰서 비교하는것까지는 알겠는데 어떻게 구현해야할지 몰라서 찾아보았다

다른사람의 코드

def solution(numbers):
    numbers = list(map(str, numbers))
    numbers.sort(key=lambda x: x*3, reverse=True)
    return str(int(''.join(numbers)))

너무 간결해서 깜짝 놀랐고 이해가 안갔다.정렬을 왜 저런 조건으로 하는지 특히 이해가 안갔다.

이리저리 찾아본걸 정리하자면 다음과 같다.

numbers.sort(key=lambda x: x*3, reverse=True) 

x*3은 문자열을 3번 곱하는 것이므로 "1"이면 "111"이 반환되고 "37"이면 "373737"이 반환된다.

"1","10","100", "1000" 을 비교한다고 가정하자

그러면 "111", "101010", "100100100", "100010001000" 끼리 비교해서 정렬한다.

숫자로만 보면 당연히 맨오른쪽이 크고 맨 왼쪽이 작은게 맞다.

하지만 문자열의 대소 비교는 문자열의 맨 앞(제일 큰자리수,각 숫자별 맨 왼쪽)부터 하게 된다.

ASCII code로 확인하면 "1"은 49이고 "0"은 48이다. 그러면 맨 앞자리 문자열부터 확인해보면

 "111" > "101010" > "100100100"> "100010001000" 이 된다.

그렇기 때문에 1>10>100>100 순이 되고 앞에서부터 추가를 하게되면 가장 큰수가 나온다.

 제대로 파이썬 4. 파이썬 연산 3) 비교 연산 -문자열의 대소비고, https://wikidocs.net/22216