프로그래머스 고득점 kit - 정렬
정렬
- 출제 빈도 높음
- 평균 점수 높음
K번째 수(Lv.1)
배열 array의 i번째 숫자부터 j번째 숫자까지 자르고 정렬했을 때, k번째에 있는 수를 구하려 합니다.
예를 들어 array가 [1, 5, 2, 6, 3, 7, 4], i = 2, j = 5, k = 3이라면
- array의 2번째부터 5번째까지 자르면 [5, 2, 6, 3]입니다.
- 1에서 나온 배열을 정렬하면 [2, 3, 5, 6]입니다.
- 2에서 나온 배열의 3번째 숫자는 5입니다.
배열 array, [i, j, k]를 원소로 가진 2차원 배열 commands가 매개변수로 주어질 때, commands의 모든 원소에 대해 앞서 설명한 연산을 적용했을 때 나온 결과를 배열에 담아 return 하도록 solution 함수를 작성해주세요.
제한사항- array의 길이는 1 이상 100 이하입니다.
- array의 각 원소는 1 이상 100 이하입니다.
- commands의 길이는 1 이상 50 이하입니다.
- commands의 각 원소는 길이가 3입니다.
array | commands | return |
[1, 5, 2, 6, 3, 7, 4] | [[2, 5, 3], [4, 4, 1], [1, 7, 3]] | [5, 6, 3] |
[1, 5, 2, 6, 3, 7, 4]를 2번째부터 5번째까지 자른 후 정렬합니다. [2, 3, 5, 6]의 세 번째 숫자는 5입니다.
[1, 5, 2, 6, 3, 7, 4]를 4번째부터 4번째까지 자른 후 정렬합니다. [6]의 첫 번째 숫자는 6입니다.
[1, 5, 2, 6, 3, 7, 4]를 1번째부터 7번째까지 자릅니다. [1, 2, 3, 4, 5, 6, 7]의 세 번째 숫자는 3입니다.
솔루션
def solution(array,commands):
return list(map(lambda x: sorted(array[x[0]-1:x[1]])[x[2]-1],commands))
- commands 내의 리스트를 하나씩 불러서 [0번째:1번째 값] 슬라이싱 후 정렬
- 정렬 후 commands 내의 리스트에서 마지막 값으로 인덱싱하여 추출한 값들을 리스트로 반환
가장 큰 수(Lv.2)
0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.
0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.
제한 사항- numbers의 길이는 1 이상 100,000 이하입니다.
- numbers의 원소는 0 이상 1,000 이하입니다.
- 정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.
numbers | return |
[6, 10, 2] | "6210" |
[3, 30, 34, 5, 9] | "9534330" |
솔루션
이 문제는 해답을 보고도 바로 이해가 가지 않아서 직접 확인하고 찾아보면서 알아냈다.
def solution(numbers):
numbers=list(map(lambda x: str(x),numbers))
numbers.sort(key=lambda x: x * 3, reverse=True)
return str(int(''.join(numbers)))
- 숫자로 입력된 값들을 문자로 변환함
- list.sort(key=None, reverse= False)
- 키값 기준으로 정렬
- 문자열 비교는 ASCII값으로 치환되어 비교된다.
-
- numbers의 인수값이 1000 이하이므로 3자리수 내에서 문자열 비교.
- 동일한 문자로 시작한다면 길이가 긴 문자열이 더 크기때문에 곱해줘서 비교 (예. '100'>'1')
- 문자 시작이 더 큰 아스키값을 갖으면 길이에 상관 없이 큼
- lambda x: x*3은 해당 문자열을 3번 곱하여 3개로 늘림 (예. '1'*3 '111')
- '100' < '111'
- [6,10,2] 의 경우 666, 101010, 222의 앞에서부터 각 인덱스 값으로 비교한다
- 6 = 54, 1 = 49, 0=48, 2 = 50 이므로 6 > 2 > 1 순으로 크다. 그러면 뒤의 값과 상관없이 첫번째 인덱스를 기반으로 666> 101010>222 로 결정된다.
- reverse = True를 통해 키값을 기준으로 리스트 값 내림차순 정렬 6 ,2,10
- ord('')로 ASCII값 확인 가능
-
print('1010'<'111')
#TRUE
print('666'>'222'>'101010')
#TRUE
- 리스트내의 문자값들을 ""기준으로 붙이기
- str, int 다시 하는 이유는 모든 값이 0으로 들어오는 경우 "000"을처리하기 위해서 먼저 "000"을 int로 변환 0, 다시 문자로 바꾸면 "0"
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
ASCII | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
H-Index(Lv.2)
H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 위키백과1에 따르면, H-Index는 다음과 같이 구합니다.
어떤 과학자가 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.
어떤 과학자가 발표한 논문의 인용 횟수를 담은 배열 citations가 매개변수로 주어질 때, 이 과학자의 H-Index를 return 하도록 solution 함수를 작성해주세요.
제한사항- 과학자가 발표한 논문의 수는 1편 이상 1,000편 이하입니다.
- 논문별 인용 횟수는 0회 이상 10,000회 이하입니다.
citations | return |
[3, 0, 6, 1, 5] | 3 |
이 과학자가 발표한 논문의 수는 5편이고, 그중 3편의 논문은 3회 이상 인용되었습니다. 그리고 나머지 2편의 논문은 3회 이하 인용되었기 때문에 이 과학자의 H-Index는 3입니다.
※ 공지 - 2019년 2월 28일 테스트 케이스가 추가되었습니다.
솔루션
처으에는 이 문제를 바로 이해하지 못하였다. '논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.'에서 h라는 값을 찾는것인데 단순하게 인덱스와 배열값을 비교해서 h이상인지를 값을 구하는 문제
방법 1.
def solution(citations):
citations.sort(reverse=True)
for i in range(len(citations)):
if citations[i] <= i:
return i
return len(citations)
예. [3, 0, 6, 1, 5] -> [6,5,3,1,0]
6<=0, 5<=1 ,3<=2 , 1<=3,0 <=4->3
5편이상 1번
방법 2.
이 방법은 enumerate을 사용한 방법으로 색다르게 푼 방법이라서 가져와봤다.
def solution(citations):
citations.sort(reverse=True)
answer = max(map(min, enumerate(citations, start=1)))
return answer
예. [3, 0, 6, 1, 5] -> [6,5,3,1,0]
enumerate :(6,1),(5,2)(3,3),(1,4),(0,5)
최소값 추출 1,2,3,1,0
최소값들 중 최대값 3
'Data > Python' 카테고리의 다른 글
[Python] 코랩(Colab) 한글 깨짐 현상 해결방법 (0) | 2022.07.08 |
---|---|
Python 코드 관리하기 (0) | 2022.01.12 |
백준 알고리즘[파이썬] 1929번: 소수 구하기 ,1978번: 소수찾기 (0) | 2021.07.22 |
[백준 알고리즘] 파이썬 - 1085번: 직사각형에서 탈출 (0) | 2021.07.16 |
정규 표현식 (Regular Expression) (0) | 2021.07.08 |