https://school.programmers.co.kr/learn/courses/30/lessons/152995
최초 코드
import java.util.*;
class Solution {
private int[] biggestA={0,0};
private int[] biggestB={0,0};
public int solution(int[][] scores) {
//1
calcBiggestOne(scores);
//2. enQueue
PriorityQueue<Score> pq = new PriorityQueue<>();
for(int i=0; i<scores.length; i++){
if(i==0){
if(!isValid(scores[i][0], scores[i][1])){
return -1;
}
pq.offer(new Score(scores[i][0],scores[i][1],true));
continue;
}
if(!isValid(scores[i][0], scores[i][1])){
continue;
}
pq.offer(new Score(scores[i][0],scores[i][1],false));
}
//3
return calcRank(pq);
}
private void calcBiggestOne(int[][] scores){
for(int i=0; i<scores.length; i++){
if(scores[i][0]>biggestA[0]){
biggestA=scores[i];
}
if(scores[i][1]>biggestB[1]){
biggestB=scores[i];
}
}
}
private int calcRank(PriorityQueue<Score> pq){
int cnt=0;
int rank=0;
Score prev=new Score(-1,-1,false);
while(!pq.isEmpty()){
Score polled = pq.poll();
cnt++;
if(polled.a+polled.b!=prev.a+prev.b){
rank=cnt;
}
prev = polled;
if(polled.isWonho){
return rank;
}
}
throw new IllegalArgumentException();
}
private boolean isValid(int currentA, int currentB){
if(currentA<biggestA[0]){
if(currentB<biggestA[1]){
return false;
}
}
if(currentB<biggestB[1]){
if(currentA<biggestB[0]){
return false;
}
}
return true;
}
class Score implements Comparable<Score>{
int a;
int b;
boolean isWonho;
Score(int a, int b, boolean isWonho){
this.a=a;
this.b=b;
this.isWonho=isWonho;
}
@Override
public int compareTo(Score o){
return (o.a+o.b)-(this.a+this.b);
}
}
}
}
시나리오
0. a(근무 태도) + b(동료 평가)를 기준으로 내림차순 정렬이 되도록 compareTo를 구현하는 Score클래스를 만든다.
- 근무 태도가 가장 큰 사원을 biggestA에 저장, 동료 평가가 가장 큰 사원을 biggestB에 저장한다.
- biggestA와 biggestB보다 두 점수 모두가 작지 않은 사원을 PriorityQueue에 enQueue한다.(얘가 엣지케이스 원인인듯)
- 원호가 몇 위인지 계산한다.
위 시나리오를 토대로 우선순위 큐를 이용해 풀어보려 했지만 아무리 개선해도 56점 까지 밖에 끌어올리지 못해 정답 코드를 구글링해보았다.
아무래도 2번 시나리오에서 biggestA와 biggestB만을 비교대상으로 삼은게 문제인듯 하다. 이 친구를 고쳐서 정답을 도출해보자.
정답 코드
import java.util.Arrays;
class Solution {
private Score[] scoreArr;
public int solution(int[][] scores) {
init(scores);
return calcRank(new Score(scores[0][0],scores[0][1]));
}
private void init(int[][] scores){
scoreArr = new Score[scores.length];
for(int i=0; i<scores.length; i++){
scoreArr[i] = new Score(scores[i][0], scores[i][1]);
}
Arrays.sort(scoreArr);
}
private int calcRank(Score wanho){
int maxPeer=0;
int rank=1;
for(Score e : scoreArr){
if(maxPeer > e.peer){
if(wanho.equals(e)){
return -1;
}
continue;
}
maxPeer = Math.max(maxPeer, e.peer);
if(wanho.getSum()<e.getSum()){
rank++;
}
}
return rank;
}
class Score implements Comparable<Score>{
int attitude;
int peer;
Score(int attitude, int peer){
this.attitude=attitude;
this.peer=peer;
}
@Override
public int compareTo(Score o){
if(o.attitude==this.attitude){
return this.peer - o.peer;
}
return o.attitude-this.attitude;
}
public boolean equals(Score o){
return this.attitude==o.attitude&&this.peer==o.peer;
}
public int getSum(){
return this.attitude+this.peer;
}
}
}
시나리오
- 근무 태도를 기준으로 내림차순 정렬 하되, 태도 점수가 같은 경우에 한해 동료 평가 점수로 오름차순 정렬하도록 compareTo를 구현한 Score클래스를 만든다.
- Score타입 배열에 기존 배열 scores요소를 삽입한다.
- 완호의 랭크를 계산. 우선 scoreArr변수를 순회하며 최대 동료평가 점수 보다 현재 사원의 동료평가 점수가 더 크면 최대 동료평가 점수를 갱신한다. 만약 완호의 점수 합보다 현재 사원의 점수 합이 더 큰 경우에만 rank++해준다. 완호보다 낮은 점수를 굳이 연산할 필요가 없기 때문이다. 이에 해당하지 않고 현재 사원의 동료평가 점수가 최대 동료평가 점수보다 작으면 인센티브를 받을 수 없는 사원이므로 연산에서 제외한다. 이유는 근무태도를 기준으로 내림차순 돼있는데 최대 동료 평가 점수보다 현재 동료평가 점수가 작다면, 현재 사원은 근무태도 점수, 동료평가 점수 모두 이전보다 작은 것이 되기 때문이다. 이 때 현재 사원이 완호라면 완호 또한 인센티브를 받을 수 없는 것이므로 return -1해준다.
'Algorithm' 카테고리의 다른 글
| LeetCode 1071. Greatest Common Divisor of Strings [Java] (0) | 2024.02.04 |
|---|---|
| [Java] 프로그래머스 - 시소 짝꿍 (0) | 2023.12.28 |
| [Java]프로그래머스 - 과제 진행하기 (0) | 2023.12.20 |
| [Java]프로그래머스 - 메뉴 리뉴얼 (0) | 2023.11.30 |
| [Java]프로그래머스 - 큰 수 만들기 (0) | 2023.11.30 |