https://school.programmers.co.kr/learn/courses/30/lessons/152995#qna
2023.08.11 기준 Level 3
알고리즘 공부를 위해 풀고 기록하는 글입니다!
참고만 해주시고 더 좋은 풀이법이 있다면 알려주세요!
아이디어
- 인센티브를 받지 못하는 사람들을 걸러낸다.
- 인센티브를 받을 수 있는 명단에서 각 사원의 점수의 합을 구한다.
- 이 점수의 합을 내림 차순으로 정렬한다.
- 완호의 점수의 위치(index)를 리턴한다.
이 흐름으로 구현을 시작했습니다.
우선 1번의 작업이 이 문제의 핵심입니다.
근무 태도 점수와 동료 평가 점수가 임의의 한 사원보다 모두 작은 사원은 인센티브를 받지 못합니다.
따라서 이런 인원을 찾아야하는데 변수가 근무 태도 점수와 동료 평가 점수로 총 2가지이기 때문에 한가지를 고정시켜야 합니다.
이를 위해 근모 태도 점수를 기준으로 내림차순으로 정렬을 했습니다.
이렇게 하면 i번째 사람은 i-1번째 사람보다 근무 태도 점수가 부족한 사람이기 때문에 동료 평가 점수는 무조건 i-1까지의 사람들보다 크거나 같은 경우가 있어야 인센티브를 받을 수 있습니다.
즉, 0부터 i-1번째 사람들 중에 동료 평가 점수의 최댓값보다 i번째 사람의 동료 평가 점수가 작다면 근무 태도는 내림차순으로 정렬되어 있기 때문에 인센티브를 받을 수 없다는 의미입니다.
하지만 여기서 1가지 더 고려해야할 것이 있습니다. 근무 태도 점수를 기준으로 내림차순을 했더라도 만약 근무 태도가 같은 사람이 있는 상황이 존재하기 때문에 이것을 고려해줘야 합니다.
만약 [5,5], [5,4], [3,5], [3,1], [2,0] 로 정렬된 상태라면 i가 1일 때 [5,4]가 인센티브를 받을 수 있는지 검사합니다. 이 때 이전까지의 동료 평가 최고점은 5입니다. 인덱스 1의 사람은 동료 평가 점수가 4이기 때문에 인센티브를 받을 수 없다고 결정나게 됩니다.
하지만 이것은 오류입니다.
[5,4]보다 두 점수 모두 앞서는 사람이 없기 때문에 인센티브 대상이어야 합니다.
근무 태도 평가 점수가 앞사람과 동률이고 앞의 사람의 동료 평가 점수가 최댓값이었기 때문에 인센티브를 받을 수 없는 사람에 속하지 않게 된 것입니다.
즉, 근무태도가 점수가 내림차순이긴 하지만 동률인 경우를 위해 근무 태도가 같은 경우에는 동료 평가 점수를 오름차순으로 정렬해주고 계산을 해야합니다. 이렇게 정렬을 했다면
[5,4], [5,5], [3,1], [3,5], [2,0] 형태가 됩니다.
이러면 [5,4]인 사람보다 [5,5]를 더 늦게 검사하기 때문에 [5,4]도 인센티브 대상에 들어가게 됩니다. (정상적인 계산이 가능해진 것입니다.)
반면 [3,1]인 사람은 이전까지의 동료 평가 최고점 5를 넘지 못했기 때문에 대상에서 제외됩니다. [2,0]도 마찬가지 입니다.
만약 완호의 점수가 제외 대상이라면 -1를 즉시 리턴하면 됩니다.
이 과정을 통해 인센티브 대상을 다 찾았으면 이제 합산 점수를 기준으로 줄세우면 됩니다.
map을 통해 합산 점수로 배열의 형태를 바꾸고 내림차순으로 정렬합니다.
[5,5,5,4,4,4,3] 이고 4가 완호의 합산 점수라면 4등입니다.
등수를 찾는 방법은 합산 점수 배열에서 완호의 함산 점수가 나오는 첫번째 인덱스에 +1을 하면 됩니다.
풀이
fileprivate func solution(_ scores:[[Int]]) -> Int {
let target = scores[0] // 완호의 점수
let attitudeScoreAscendingSorted = scores.sorted(by: { $0[0] > $1[0] || ($0[0] == $1[0] && $0[1] < $1[1]) })
var maxPeerEvaluationScore = attitudeScoreAscendingSorted.first![1]
var peopleCanGetIncentive = [[Int]]()
for score in attitudeScoreAscendingSorted {
if maxPeerEvaluationScore > score[1] {
if score == target { return -1 }
continue
} else {
peopleCanGetIncentive.append(score)
}
maxPeerEvaluationScore = max(maxPeerEvaluationScore, score[1])
}
let overallScore = peopleCanGetIncentive.map { $0[0] + $0[1] }.sorted(by: >)
guard let ranking = overallScore.firstIndex(of: target.reduce(0, +)) else {
return -1
}
return ranking + 1
}
attitudeScoreAscendingSorted 배열을 구하는 정렬 조건이 주요했습니다.
근무 태도는 내림차순, 만약 근무 태도가 같은 값이면 동료 평가를 오름차순으로!
마무리
간단한 문제 같았지만 정렬 조건을 잘 설정해야 했습니다.
이렇게 2가지의 변수가 비교 대상이라면 한쪽을 기준점으로 잡고 오름/내림 차순으로 하여 비교 대상에서 제외시키는 방식을 사용해야 한다는 것을 배웠습니다.
'알고리즘' 카테고리의 다른 글
[프로그래머스] Swift - 양과 늑대 (0) | 2023.08.16 |
---|---|
[프로그래머스] Swift - 광고 삽입 (0) | 2023.08.15 |
[프로그래머스] Swift - 기둥과 보 설치 (0) | 2023.08.10 |
[프로그래머스] Swift - 표 편집 (0) | 2023.08.08 |
[프로그래머스] Swift - 길 찾기 게임 (0) | 2023.08.07 |
댓글