본문 바로가기

프로그래머스 코딩(자바)/Level 0

Programmers Level 0 - 특이한 정렬

728x90

문제 설명

정수 n을 기준으로 n과 가까운 수부터 정렬하려고 합니다. 이때 n으로부터의 거리가 같다면 더 큰 수를 앞에 오도록 배치합니다. 정수가 담긴 배열 numlist와 정수 n이 주어질 때 numlist의 원소를 n으로부터 가까운 순서대로 정렬한 배열을 return하도록 solution 함수를 완성해주세요.

 
제한사항
  • 1 ≤ n ≤ 10,000
  • 1 ≤ numlist의 원소 ≤ 10,000
  • 1 ≤ numlist의 길이 ≤ 100
  • numlist는 중복된 원소를 갖지 않습니다.

 

입출력 예
numlist n result
[1, 2, 3, 4, 5, 6] 4 [4, 5, 3, 6, 2, 1]
[10000,20,36,47,40,6,10,7000] 30 [36, 40, 20, 47, 10, 6, 7000, 10000]

입출력 예 설명

입출력 예 #1

  • 4에서 가까운 순으로 [4, 5, 3, 6, 2, 1]을 return합니다.
  • 3과 5는 거리가 같으므로 더 큰 5가 앞에 와야 합니다.
  • 2와 6은 거리가 같으므로 더 큰 6이 앞에 와야 합니다.

입출력 예 #2

  • 30에서 가까운 순으로 [36, 40, 20, 47, 10, 6, 7000, 10000]을 return합니다.
  • 20과 40은 거리가 같으므로 더 큰 40이 앞에 와야 합니다.

 

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
import java.util.Arrays;
class Solution {
    public int[] solution(int[] numlist, int n) {
        int[] answer = new int[numlist.length];
        int ar[] = new int[numlist.length];
        Arrays.sort(numlist);
        for(int i=0;i<numlist.length/2;i++) {
            int t = numlist[i];
            numlist[i] = numlist[numlist.length-1-i];
            numlist[numlist.length-1-i] = t;
        }
        for(int i=0;i<numlist.length;i++) ar[i] = Math.abs(numlist[i]-n);
        for(int i=0;i<answer.length;i++) {
            int min = ar[0];
            int index = 0;
            for(int j=1;j<ar.length;j++) {
                if(min>ar[j]) {
                    min = ar[j];
                    index = j;
                }
            }
            ar[index] = 10001;
            answer[i] = numlist[index];
        }
        return answer;
    }
}
cs

 

  배열을 내림차순 정렬한다.

        Arrays.sort(numlist); // 오름 차순 정렬
        // 배열 뒤집기
        for(int i=0;i<numlist.length/2;i++) {
            int t = numlist[i];
            numlist[i] = numlist[numlist.length-1-i];
            numlist[numlist.length-1-i] = t;
        }

  절대값을 구해 배열에 넣는다.
  for(int i=0;i<numlist.length;i++) ar[i] = Math.abs(numlist[i]-n);

   절대값이 적은 위치를 찾아 그 위치에 배열값을 넣는다.
  for(int i=0;i<answer.length;i++) {
         int min = ar[0];
         int index = 0;
         for(int j=1;j<ar.length;j++) {
               if(min>ar[j]) {
                    min = ar[j];
                     index = j;
               }
         }
         ar[index] = 10001;   // 이미 구했으므로 아주 큰값으로 바꿔준다. 제외시키기 위해
         answer[i] = numlist[index];
   }

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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();
    }
}
cs

 

   위의 문제에서 정렬 기준을 어떻게 주느냐가 관건이다.

    sorted()메서드의 인수로 Comparator<? super Integer> comparator 인터페이스를 구현한 객체를 리턴해주어 하는데
    같을 경우 0 앞의 값이 크면 양수를 뒤의 값이 크면 음수를 리턴 하도록 만든다.
    
   아래와 같이 만들어도 가능하다. 위의 식은 람다를 이용한 것이다.
    

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.Arrays;
class Solution {
    public int[] solution(int[] numlist, int n) {
        return Arrays.stream(numlist)
                .boxed()
                .sorted(new Comparator<Integer>() {
                    @Override
                    public int compare(Integer o1, Integer o2) {
                        // 두개의 절대 값이 같다면 
                        return Math.abs(o1-n)==Math.abs(o2-n) ?  
                                // 뒤의 큰값이 되도록 하고 (o2, o1)
                                o2.compareTo(o1) : 
                                // 아니면 앞의 값을 기준으로 한다.(o1, o2) 
                                Integer.compare(Math.abs(o1 - n), Math.abs(o2 - n)); 
                    }
                })
                .mapToInt(Integer::intValue)
                .toArray();
    }
}
cs

 

728x90