생각정리/코딩테스트

[JAVA][Level1]PROGRAMMERS 숫자 짝꿍

생각중임 2023. 8. 23. 22:57

 

숫자 짝꿍


문제 설명

두 정수 X, Y의 임의의 자리에서 공통으로 나타나는 정수 k(0 ≤ k ≤ 9)들을 이용하여 만들 수 있는 가장 큰 정수를 두 수의 짝꿍이라 합니다(단, 공통으로 나타나는 정수 중 서로 짝지을 수 있는 숫자만 사용합니다). X, Y의 짝꿍이 존재하지 않으면, 짝꿍은 -1입니다. X, Y의 짝꿍이 0으로만 구성되어 있다면, 짝꿍은 0입니다.

예를 들어, X = 3403이고 Y = 13203이라면, X와 Y의 짝꿍은 X와 Y에서 공통으로 나타나는 3, 0, 3으로 만들 수 있는 가장 큰 정수인 330입니다. 다른 예시로 X = 5525이고 Y = 1255이면 X와 Y의 짝꿍은 X와 Y에서 공통으로 나타나는 2, 5, 5로 만들 수 있는 가장 큰 정수인 552입니다(X에는 5가 3개, Y에는 5가 2개 나타나므로 남는 5 한 개는 짝 지을 수 없습니다.)
두 정수 X, Y가 주어졌을 때, X, Y의 짝꿍을 return하는 solution 함수를 완성해주세요.

제한사항

  • 3 ≤ X, Y의 길이(자릿수) ≤ 3,000,000입니다.
  • X, Y는 0으로 시작하지 않습니다.
  • X, Y의 짝꿍은 상당히 큰 정수일 수 있으므로, 문자열로 반환합니다.

입출력 예

X Y result
"100" "2345" "-1"
"100" "203045" "0"
"100" "123450" "10"
"12321" "42531" "321"
"5525" "1255" "552"

입출력 예 설명

입출력 예 #1

X, Y의 짝꿍은 존재하지 않습니다. 따라서 "-1"을 return합니다.

입출력 예 #2

X, Y의 공통된 숫자는 0으로만 구성되어 있기 때문에, 두 수의 짝꿍은 정수 0입니다. 따라서 "0"을 return합니다.

입출력 예 #3

X, Y의 짝꿍은 10이므로, "10"을 return합니다.

입출력 예 #4

X, Y의 짝꿍은 321입니다. 따라서 "321"을 return합니다.

입출력 예 #5

지문에 설명된 예시와 같습니다.

주어진 문제

class Solution {
    public String solution(String X, String Y) {
        String answer = "";
        return answer;
    }
}

나의 문제풀이

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Solution {
    public String solution(String X, String Y) {
        // 정렬한 문자열을 뒤집어서 출력하기 위해 사용
        StringBuilder answer = new StringBuilder();
        List<Integer> pair = new ArrayList<>();

        // X와 Y를 정렬하여 사용한다.
        char[] x = X.toCharArray();
        char[] y = Y.toCharArray();
        Arrays.sort(x);
        Arrays.sort(y);
        X = new String(x);
        Y = new String(y);

        // 짝꿍의 수를 구한다.
        int sum = 0;
        for (int i = 0; i < 10; i++) { // 0~9까지의 짝궁의 수를 구한다.
            int x_fir = X.indexOf(String.valueOf(i)); // 없으면 -1 출력
            int x_las = X.lastIndexOf(String.valueOf(i));
            int y_fir = Y.indexOf(String.valueOf(i));
            int y_las = Y.lastIndexOf(String.valueOf(i));
            // -1일경우 숫자가 없고, 첫 번째 인덱스와 마지막 인덱스가 같은 경우 한 개이고,
            // 나머지는 마지막 인덱스 - 첫 번째 인덱스 + 1을 하면 해당 글자를 가지고 있는 수이다
            int x_len = x_las == -1 ? 0 : x_las == x_fir ? 1 : x_las - x_fir + 1;
            int y_len = y_las == -1 ? 0 : y_las == y_fir ? 1 : y_las - y_fir + 1;

            // 비교 하여 작은 수 만큼 짝꿍이 될 수 있다.
            pair.add(x_len > y_len? y_len:x_len);
            sum += pair.get(i);
        }

        if (sum == 0) { // 짝꿍이 한명도 없으면 -1
            answer.append("-1");
        } else if (sum == pair.get(0)) { // 짝꿍의 수가 0의 수이면 전부 0
            answer.append("0");
        } else {
            int cnt = 0;
            while (pair.iterator().hasNext()) { // 해당 숫자의 짝꿍 수만큼 문자열 생성
                answer.append(String.valueOf(cnt++).repeat(pair.iterator().next()));
                pair.remove(0);
            }
        }
        // -1을 제외하고 뒤집어서 정렬해준다.
        return answer.toString().equals("-1")? answer.toString():answer.reverse().toString();
    }
}
  • 0~9까지의 짝꿍의 수를 넣을 list와 완성 문자열을 넣어줄 StringBuilder를 선언해 준다.
  • 자릿수를 비교하기 쉽게 X와 Y를 오름차순 정렬을 해준다.
  • 0~9까지 for-loop로 반복해주면서 X와 Y에서 해당 숫자가 있는 첫 번째와 마지막 인덱스 위치를 체크해 개수를 계산한다. (한 개일 경우 인덱스 위치가 같아 0이기 때문에 1로 만들어 주고 없을 경우 -1이기 때문에 0으로 고정해 준다. 나머지는 마지막 인덱스에 첫 번째 인덱스를 빼고 + 1을 해주면 가지고 있는 개수가 된다.)
  • 짝꿍이기 때문에 해당 숫자를 가지고 있는 X와 Y의 개수 중 작은 수를 list에 넣어준다.
  • 총 짝꿍수를 헤아리기 위해서 리스트의 값을 넣어준다.
  • 모든 수를 확인했을 때 합이 0이면 짝꿍이 없이 때문에 최종 출력을 -1로 한다.
  • 합과 리스트의 0 개수가 같을 경우 0 빼고 짝꿍은 없이 때문에 최종 출력을 0으로 한다.
  • 그게 아니라면 리스트에 들어있는 숫자를 0부터 9까지 전부 sb에 넣어준 다음 -1을 제외일 경우 뒤집어서 출력해준다.

범위가 적기 때문에 for-loop를 이용해서 했고, 고정된 고정된 문자들이기 때문에 인덱스를 이용해서 개수를 헤아릴 수 있었다.
짝꿍의 수를 구한 이후에는 조건만 잘 보면 간단히 구현할 수 있는 부분인데 -1은 뒤집으면 안 되는 점등 사소한 것만 안 놓치면 될 거 같았다. 또한, 팀원들과 코드리뷰도 하고 따로 내용을 정리하다 보니 리스트를 사용하지 않고 짝꿍수를 구하면서 바로 문자열로 넣어서 구현을 할 수 있을 거 같아 나중에 리팩토링을 한번 다시 해봐야겠다.

 

 

문제 출처 - https://school.programmers.co.kr/learn/courses/30/lessons/131128