생각해볼 점
1. 정석대로 커스텀 정렬을 이용해 풀기
2. if문으로 분기조건 설정해서 풀기
1번으로 풀면 예외가 존재할 수가 없다. 그러나 나는 사파인 2번으로 문제풀이를 전개했기 때문에, 예외사항을 잘 처리했는지가 문제를 풀 때 생각했던 포인트였다. 이 문제를 통해 좋은 테스트케이스를 어떻게 작성해야하는지에 대해 인사이트가 조금은 생긴 것 같다.
테스트 케이스는 엣지 케이스여야 한다.
이 문제에서 생각해볼 법한 테스트케이스는 다음과 같다.
- n이 list의 원소인가
- n이 list의 원소들은 아니지만, 정렬했을 때 가장 큰 값과 가장 작은값의 범위 사이에 존재하는가
- n이 list의 원소중 최솟값보다 작은가
- n이 list의 원소중 최솟값과 같은가
- n이 list의 원소중 최댓값보다 큰가
- n이 list의 원소중 최댓값인가
다음을 모두 만족했을 때 웬만한 모든 테스트 케이스를 통과할 수 있고, 나는 해당 테스트케이스를 만족하도록 코드를 짜서 통과할 수 있었다. 그래서 내 코드는 다음과 같다.
1. 본인 코드
import java.util.*;
import java.util.stream.*;
class Solution {
public int[] solution(int[] numlist, int n) {
int[] answer = {};
List<Integer> list = new LinkedList<>();
Arrays.sort(numlist);
int minIdx = -1;
int plusIdx = numlist.length;
for(int i = 0; i < numlist.length; i++){
if(numlist[i] == n){
list.add(numlist[i]);
minIdx = i-1;
plusIdx = i+1;
break;
} else if(i+1 != numlist.length && numlist[i] < n && numlist[i+1] > n){
minIdx = i;
plusIdx = i+1;
break;
} else if(numlist[0] > n){
plusIdx = 0;
break;
} else if(numlist[numlist.length - 1] < n){
minIdx = numlist.length -1;
break;
}
}
while(minIdx != -1 || plusIdx != numlist.length){
if(minIdx != -1 && plusIdx != numlist.length){
int mindist = n - numlist[minIdx];
int maxdist = numlist[plusIdx] - n;
if(maxdist < mindist){
list.add(numlist[plusIdx++]);
} else if(maxdist > mindist) {
list.add(numlist[minIdx--]);
} else{
if(numlist[minIdx] > numlist[plusIdx]){
list.add(numlist[minIdx--]);
} else {
list.add(numlist[plusIdx++]);
}
}
} else if(minIdx == -1){
list.add(numlist[plusIdx++]);
} else if(plusIdx == numlist.length){
list.add(numlist[minIdx--]);
}
}
return list.stream().mapToInt(i -> i).toArray();
}
}
더 쉽게 작성한 분이 있는지 궁금해서 다른 분들의 풀이를 구경한 결과 배울만한 코드는 다음과 같았다.
일단 다른 분들은 comparator을 이용한 분들이 많았다. 이름부터가 정렬이다 보니 다른 분들은 정렬로 푸신 것을 볼 수 있는데 사실 아래 코드가 좀 더 정석인 것 같다. 보면서 정렬에 더 익숙해질 수 있었다.
다른 분 풀이 1
import java.util.Arrays;
class Solution {
public int[] solution(int[] numList, int n) {
return Arrays.stream(numList)
.boxed()
.sorted((a, b) -> Math.abs(a - n) == Math.abs(b - n) ? b.compareTo(a) : Integer.compare(Math.abs(a - n), Math.abs(b - n)))
.mapToInt(Integer::intValue)
.toArray();
}
}
풀이 분석
1. boxed
int를 Integer로 감싸줄 때 사용한다. sorted와 같은 함수를 사용하기 위해 쓴 것 같다.
2. Integer::intValue
mapToInt함수의 인자로 주어진 Integer::intValue는 Integer 클래스의 intValue 함수를 값으로 넘겨줘서 사용한 것이다. 이에 관련해서는 추가 공부 후 링크 청부하겠다.
3. sorted 부분
- 조건1 : 거리가 같다면, 더 큰 값을 먼저 내보낸다(내림차순)
- compareTo 함수의 구현은 다음과 같이 되어있다.
//compareTo 함수 구현부 public int compareTo(Integer anotherInteger) { return compare(this.value, anotherInteger.value); } //compare 함수 구현부 public static int compare(int x, int y) { return (x < y) ? -1 : ((x == y) ? 0 : 1); }
- ` b.compareTo(a) `
- 정렬의 로직은 음수, 0, 양수 순으로 정렬된다.
- 함수의 결과가 음수일 때, b가 앞에 온다.
- 함수의 결과가 양수일 때, a가 앞에 온다.
- compare(x, y) 함수는 앞에 있는 게 작을 때 음수, 클 때 양수이다. (기본적으로 오름차순)
- 근데, 현재 compare의 인수가 거꾸로 주어져있다. 그러므로 내림차순 정렬이 적용되는 것이다.
- compareTo 함수의 구현은 다음과 같이 되어있다.
- 거리가 다르다면, 더 가까운 거리 순으로 Integer의 내장함수 compare 함수를 사용한다.다른 분 풀이 2
import java.util.PriorityQueue;
class Solution {
public int[] solution(int[] numlist, int n) {
PriorityQueue<Integer> que = new PriorityQueue<>(
(a, b) -> Math.abs(a - n) == Math.abs(b - n) ? b - a : Math.abs(a - n) - Math.abs(b - n));
for (int num : numlist)
que.add(num);
int idx = 0;
while (!que.isEmpty())
numlist[idx++] = que.poll();
return numlist;
}
}
'코딩테스트 > Programmers' 카테고리의 다른 글
[프로그래머스] 문자열을 정수로 바꾸기 (0) | 2025.02.18 |
---|---|
[프로그래머스] 저주의 숫자 3 (0) | 2025.01.31 |
[프로그래머스] 최빈값 구하기 (0) | 2025.01.29 |
[프로그래머스] PCCE 기출문제 10번 / 데이터 분석 (0) | 2025.01.26 |
[프로그래머스] PCCE 기출문제 10번 / 공원 (0) | 2025.01.26 |