반응형

문제풀이

 주어진 조건에 맞게 정렬하는 문제이다. 

 1. 장르별로 각 곡이 몇 번 재생되었는지를 가지고 있는 딕셔너리(g_songs)와 각 장르가 총 몇번 재생되었는지를 가지고 있는 딕셔너리(g_num)을 선언한 뒤, 주어진 genres와 plays에서 하나씩 꺼내며 적절히 넣는다.

* g_songs는 key 가 장르명이고 value는 (곡 번호, 재생수))인 튜플들로 이루어진 리스트이다.

* g_num은 key가 장르명이고 value는 그 장르의 모든 곡들의 재생수의 합이다.

 

 2. 주어진 곡들을 모두 넣은 후, g_num의 key를 value에 따라 정렬한다. (정렬의 첫번째 조건인 "속한 노래가 많이 재생된 장르를 먼저 수록합니다."를 먼저 수행)

 3. 2에서 정렬된 순서대로 각 장르별로 g_songs에서 value들을 가져와 각 곡의 재생수인 튜플의 두번째 요소로 정렬한 후, 같다면 곡 번호인 튜플의 첫번째 요소로 정렬해 준다. (정렬의 두, 세번째 조건 수행)

Python Code

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
39
40
from functools import cmp_to_key
 
def comparator(x, y):
    if x[1< y[1] : 
        return 1 
    elif x[1> y[1] :
        return -1
    else :
        if x[0< y[0] :
            return -1
        else :
            return 1
            
def solution(genres, plays):
    g_songs = {}
    g_num = {}
 
    for i in range(len(plays)):
        if genres[i] in g_songs :
            temp= g_songs[genres[i]]
            temp.append([i,plays[i]])
            g_songs[genres[i]] = temp
            g_num[genres[i]] = g_num[genres[i]] + plays[i]
        else :
            g_songs[genres[i]] = [[i,plays[i]]]
            g_num[genres[i]] = plays[i]
 
    genre_set = list(g_num.keys())
    genre_set.sort(key=lambda el:g_num[el], reverse=True)
 
    best = []
    
    for g in genre_set:
        temp = sorted(g_songs[g], key=cmp_to_key(comparator))
        if len(temp)==1:
            best.append(temp[0][0])
        else :
            for i in range(2):
                best.append(temp[i][0])
    return best
cs

Line 3의 comparator 함수는 과정 3을 수행하는 함수로 cmp_to_key 를 이용하여 line 34에서 sort함수의 key로 활용됩니다.

Line 18 의 i는 각 곡의 고유 번호로, for문은 과정 1을 수행합니다.

Line 28 ~ 29는 과정 2의 장르를 장르별 총 재생수로 정렬하는 과정입니다.

Line 34는 장르별로 해당 곡들을 꺼내와 정렬하는 과정입니다.

문제 링크

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

반응형
반응형

문제풀이

 works의 요소들의 제곱의 합이 가장 작게 하면 되는 문제로, works 요소들에서 주어진 n만큼을 적절히 빼서 works의 요소들의 최댓값을 가장 작게 만들어주면 된다. 따라서 가장 단순한 풀이로는, works를 정렬해가며 최댓값인 요소에서 1씩 빼는 과정을 n번 반복하면 된다. 

 하지만 위와 같은 방법으로 풀게되면, 당연히 효율이 좋지 못하므로, 더 효율적인 풀이를 고려해야한다. 제 풀이는 다음과 같습니다.

 1. works를 정렬한 후, i를 1씩 늘려가며 works의 i-1번째 요소까지의 모든 요소들의 값을 같게 하는데,

 1-1. 만약 works의 0번째부터 i-1번째 요소들을 모두 i번째 요소와 같도록 만들 수 있다면 바꾼 후, 바꿔준 만큼 n에서 빼줍니다.

 1-2. 불가능하다면 1과정을 멈춘다.

 2. 1-1을 거쳐 값을 똑같이 맞춰줄 수 있었던 요소들에 대하여 남은 n을 공평하게 배분한다.

 3. 남은 값들을 앞에서부터 1씩 배분한다.

 

예시

 works = [3,5,7], n = 3인 경우를 예로 들어보면 다음과 같다.

t n works[0] works[1] works[2]
0 3 7 5 3
1 1 5 5 3
2 1 5 5 3
3 0 4 5 3

알고리즘이 동작하는 과정을 편의상 t라고 했습니다. 

t=0은 과정 1의 정렬을 하는 과정입니다.

t=1은 works의 두번째 요소(works[1])까지의 요소들의 값들이 같도록 만드는 과정입니다. works[0]을  works[1]과 같도록 만들 수 있으므로 바꾸어주고 n에서 works[0]-works[1]을 빼줍니다. i가 2 이상이라면 i*(works[i-1]-works[i])를 빼주면 됩니다. 

t=2는 과정 2인데, 0이 아닌 요소가 3개인데, n은 1이므로 이 과정은 진행되지 않지만, 이해를 돕기위해 넣었습니다.

t=3은 과정 3으로, 남아있는 n을 앞에서부터 1씩 처리하는 과정입니다.

이제 t=3에서의 요소의 값들을 제곱하여 반환하면 됩니다.

 

* 시간복잡도는 최악의 경우 for문 3번으로 끝나므로, works의 길이를 N이라 하면 O(NlonN + N)이 됩니다(정확히는 O(NlonN + 3N)).

Python Code

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
def solution(n, works):
    if sum(works) <=n: return 0
    works.sort(reverse=True)
    
    equal = len(works)
    for i in range(1,len(works)):
        d = works[i-1]-works[i]
        if d==0:
            continue
        elif d*i<=n:
            for j in range(i):
                works[j] = works[i]
                n-=d
        else :
            equal = i
            break
            
    # 다 똑같아졌다.
    assign = n//equal
    for i in range(equal):
        works[i] -= assign
        n-=assign
    for i in range(n):
        works[i]-=1
    return sum(x**2 for x in works)
cs

line 6의 for문이 과정 1(equal index까지 요소들의 값이 같게 됩니다.),

line 19이 n을 공평하게 처리하는 부분,

line 23이 남은 n을 1씩 앞에서부터 처리하는 부분입니다.

 

문제링크

 

코딩테스트 연습 - 야근 지수 | 프로그래머스

회사원 Demi는 가끔은 야근을 하는데요, 야근을 하면 야근 피로도가 쌓입니다. 야근 피로도는 야근을 시작한 시점에서 남은 일의 작업량을 제곱하여 더한 값입니다. Demi는 N시간 동안 야근 피로도를 최소화하도록 일할 겁니다.Demi가 1시간 동안 작업량 1만큼을 처리할 수 있다고 할 때, 퇴근까지 남은 N 시간과 각 일에 대한 작업량 works에 대해 야근 피로도를 최소화한 값을 리턴하는 함수 solution을 완성해주세요. 제한 사항 works는 길이

programmers.co.kr

 

반응형

+ Recent posts