문제 출처

https://school.programmers.co.kr/learn/courses/30/lessons/42746(프로그래머스)

학습 키워드

정렬

시도 방법

(1) 숫자를 내림차순 정렬해야 가장 큰 숫자가 앞에 나오니 큰 수가 된다.
(2) 다만 "숫자형"으로 하면 원하는 결과가 나오지 않아 "문자형"으로 비교했다.
(3) 이후 비교 결과를 기준으로 숫자를 StringBuilder에 추가해 제출했다.
자세한 설명은 아래 코드를 참고하면 이해가 쉽다.

내가 작성한 코드

import java.util.ArrayList; 
import java.util.Collections; 

class Solution {
    public String solution(int[] numbers) { 
    
        StringBuilder result = new StringBuilder(); 
    
        ArrayList<String> arrList = new ArrayList<>(); 
        
        for(int i = 0 ; i<numbers.length; i++) {
            arrList.add( String.valueOf(numbers[i]).repeat(4)); 
        }
        
        Collections.sort(arrList , Collections.reverseOrder()); 
        
        if(arrList.get(0).equals("0000")) return "0"; 
        
        for(int i = 0 ; i<arrList.size() ; i++) {
            String tmp = arrList.get(i); 
            result.append( tmp.substring(0 , tmp.length()/4 ) );
        }
        
        return result.toString(); 
    }
    
}

코드설명

먼저 ArrayList<String>에 numbers 배열의 int를 String으로 변환해 값을 추가하고 있다.
중요한 점은 repeat(4) 부분인데. 이는 문자열을 n회 반복 입력하겠다는 의미이다.

ex) "안녕".repeat(4) ==> "안녕안녕안녕안녕"

만약 숫자 3,30,34,9가 있다면 숫자를 기준으로 34 , 30 , 9 , 3 순으로 역순 정렬이 되고
이렇게 되면 343093이 출력되는데 , 이는 934330보다 작은 값이므로 틀린 값이 된다.

이는 숫자의 길이때문에 발생한 문제이며, 문제 조건을 보면 각 원소는 최대 1000 이라고 하니 모든 숫자를 4배씩 repeat 처리했다.

ex)
30 -> "30" -> "30303030"
34 -> "34" -> "34343434"
9 -> "9" -> "9999"
3 -> "3" -> "3333"

문자열은 사전 순으로 정렬되므로 9999 , 34343434 , 3333, 30303030 순으로 역순 정렬하게 된다.

마지막으로 답에 추가할때는 다시 4배했던 대상을 substring으로 처음부터 1/4 길이 까지만 append을 한다.

ex) substring(n , m)
9 -> "9" -> "9999" -> "9" (0~1)
34 -> "34" -> "34343434" -> "34" (0~2)
3 -> "3" -> "3333" -> "3" (0~1)
30 -> "30" -> "30303030" -> "30" (0~2)

이를 합치면 "934330" 이 된다.

실행결과

새롭게 알게된 점

(1) String의 repeat 메서드로 문자열을 반복처리 할 수 있는 점을 배울 수 있었다.

(2) 추가로 정렬을 직접 구현할 수 있는 new Comparator 에 대해 추가로 배울 수 있었다.

import java.util.Comparator;

// Comparator<레퍼런스> 인터페이스를 구현한다.
public class AgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return Integer.compare(p1.getAge(), p2.getAge());
    }    
    //여기서는 Person객체의 나이정보 크기를 비교해 리턴 처리를 한다. 
}

...

Arrays.sort(people, new AgeComparator()); //정렬시 내가 만든 정렬기준을 이용

(3) Comparator 인터페이스의 주요 기능 (java.util.Comparator)

  • compare(T o1 , T o2) : 두 객체 비교.
    o1 < o2 이면 음수 , o1 == o2 이면 0 , o1 > o2 이면 양수 리턴

  • reversed() : 현재 Comparator의 순서를 반대로 바꾼다.

  • thenComparing() : 기본 Comparator 비교 후 결과가 동일하면 그 다음 Comparator를 사용한다.

  • reverseOrder() : 객체의 정렬된 순서롤 반대로 반환

  • comparing() : 키 추출 함수를 이용해 특정 키에 대한 값을 기준으로 비교할 수 있다.


List<Person> people 에는 P("김씨" ,25) , P("강씨 , 30) , P("최씨", 27) 가 있다고 가정


// 나이순정렬 (comparing 뒤에 Person 객체의 getAge 메서드 활용) 
people.sort(Comparator.comparing(Person::getAge));

// 나이 순으로 정렬 후, 같은 나이인 경우 이름 순으로 정렬
people.sort(Comparator.comparing(Person::getAge)
                      .thenComparing(Person::getName));

// 나이 역순으로 정렬
people.sort(Comparator.comparing(Person::getAge).reversed());

//나이순 정렬 (단 null을 맨 먼저 출력) 
peopleWithNulls.sort(Comparator.nullsFirst(Comparator.comparing(Person::getAge)));

다음에 풀어볼 문제 - H-index



#99클럽 #코딩테스트 준비 #개발자 취업 #항해99 #TIL

profile
Backend Developer (Financial)

0개의 댓글