알고리즘/항해99

99클럽 코테 스터디 7일차 TIL + 정렬(가장 큰 수)

IamBD 2024. 5. 26. 14:47

오늘의 과제

프로그래머스 Lv.2에 정렬로 분류된 가장 큰 수입니다.

 

역시 기본적인 정렬에 대한 문제인 것 같습니다.

문제

https://school.programmers.co.kr/learn/courses/30/lessons/42746?language=java

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

문제를 살펴보면 0 이상의 양의 정수가 주어졌을 때 위치를 조정하여 가장 큰 수를 문자열로 반환하면 됩니다.

 

문제를 풀 때 유의할 점은 0 이상의 정수로 0 또한 주어질 수 있다는 점입니다.

 

입력 제한으로는 1 이상 100,000 이하이니 완전 탐색으로 접근시 시간 제한으로 풀 수 없으니

되도록 한 번의 반복으로 처리할 수 있어야 합니다.

 

즉, 입력 배열을 순회할 때마다 정렬이 되어야 합니다.

 

문자를 붙여봐서 더 큰 값을 알아내야 하니 일반적인 숫자 비교가 아닌 붙여놓고 비교해야 합니다.

 

입력 예제 1번을 보면 6, 10, 2 라고 있을 때 610, 106 이렇게 양 방향으로 붙여보고 비교합니다.

 

위 조건들을 정리했을 때 문제의 설계는 다음과 같습니다.

  1. 숫자 배열을 문자 배열로 바꾼다.
  2. 문자 배열을 비교하는데 정렬 기준은 두 문자를 이어붙여 비교한다.
  3. 모든 문자가 정렬되면 이어붙여 하나의 문자열을 만들어 반환한다.
  4. 입력에 0만 들어올 수 있으니 정렬된 문자가 0인지 확인한다.

 

설계대로 구현한 풀이 코드입니다.

import java.util.*;

class Solution {
    public String solution(int[] numbers) {
        // 계산을 위해 정수 배열을 문자열 배열로 변환
        String[] numberToString = Arrays.stream(numbers)
            .mapToObj(String::valueOf)
            .toArray(String[]::new);
        
        Arrays.sort(numberToString, (a, b) -> {
            // 두 숫자를 이어붙인 결과를 비교
            String order1 = a + b;
            String order2 = b + a;
            return order2.compareTo(order1);
        });
        
        // 정렬된 문자열을 이어붙임
        StringBuilder largestNum = new StringBuilder();
        for (String s : numberToString) largestNum.append(s);
        
        // 모든 숫자가 0일 경우 "0" 반환
        if (largestNum.charAt(0) == '0') return "0";
        return largestNum.toString();
    }
}

 

배운 점

오랫만에 만나는 정렬 문제입니다.

 

사실 Comparator 구현하는 방법을 까먹어서 대부분의 풀이 시간을 사용법을 익히는데 사용한 것 같습니다.

 

예전 기억으로는 정렬 관련하여 Comparator를 구현할 일이 많았던 것 같아

이번 문제에 사용한 김에 확실히 사용법을 익혀두면 추후 문제 풀이에 큰 도움이 될 것 같습니다.

 

 

오늘의 한줄평

Lv.3 이하는 유형별 풀이 방법이 정형화 되어 있다. 자주 쓰이는 API 반드시 기억하자.