[programmers] 숫자 짝꿍

김태민·2022년 10월 12일
0

알고리즘

목록 보기
74/77

mingssssss

1. 문제


2. 코드

import java.util.*;

class Solution {
    public String solution(String X, String Y) {
        
        List temp = new ArrayList<>();
        int[] cnt = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        
//         // 1. 길이가 짧은 문자열을 잘라서 다른 쪽에 해당 문자가 들어있는지 확인(자리수까지 비교 필요)
//         if (X.length() <= Y.length()) {
            
//             for (int i = 0; i < X.length(); i++) {
                
//                 if (Y.contains(String.valueOf(X.charAt(i)))) {
                    
//                     // 2. 들어있다면 int 배열에 저장
//                     //temp.add(Integer.parseInt(String.valueOf(X.charAt(i))));
//                     temp.add(X.charAt(i));
//                     // 2-1 해당 숫자 삭제
//                     Y = Y.replaceFirst(String.valueOf(X.charAt(i)), "");
//                 }
//             }
//         } else {
            
//             for (int j = 0; j < Y.length(); j++) {
                
//                 if (X.contains(String.valueOf(Y.charAt(j)))) {
                    
//                     // 2. 들어있다면 int 배열에 저장
//                     //temp.add(Integer.parseInt(String.valueOf(Y.charAt(j))));
//                     temp.add(Y.charAt(j));
//                     // 2-1 해당 숫자 삭제
//                     X = X.replaceFirst(String.valueOf(Y.charAt(j)), "");
//                 }
//             }
            
//         }
        
        // X를 순회하면서 각 자리의 숫자가 몇 번 나왔는지 count
        for (int i = 0; i < X.length(); i++) {
            cnt[Integer.parseInt(String.valueOf(X.charAt(i)))]++;
        }
        
        // Y를 순회하면서 각 자리 숫자가 0보다 많이 나왔다면 리스트에 추가하고 해당 자리 숫자 1 감소
        for (int i = 0; i < Y.length(); i++) {
            if (cnt[Integer.parseInt(String.valueOf(Y.charAt(i)))] > 0) {
                temp.add(Y.charAt(i));
                cnt[Integer.parseInt(String.valueOf(Y.charAt(i)))]--;
            }
        }
        
        // 짝꿍이 존재하지 않는 경우
        if (temp.size() == 0) {
            return "-1";
        }
        
        // 3. 배열 정렬
        Collections.sort(temp, Collections.reverseOrder());
        
        // 짝꿍이 0으로만 구성되어 있는 경우
        if (String.valueOf(temp.get(0)).equals("0")) {
            return "0";
        }
        
        StringBuilder answer = new StringBuilder();
        // 4. 정렬된 문자 붙이기
        for (int i = 0; i < temp.size(); i++) {
            answer.append(String.valueOf(temp.get(i)));
        }
        
        return answer.toString();
    }
}

3. 리뷰

주석 처리된 부분은 처음 생각했던 로직이다. 다들 처음엔 이 로직을 생각했겠지만, 이 로직은 형변환과 탐색 시간 초과로 인해 11~15번의 테스트케이스가 시간초과가 났다.

구선생님의 도움으로 힌트를 찾아 문자열 자체를 비교하는 것이 아닌,
0~9까지의 숫자를 비교하는 방식으로 풀었다.

먼저 0~9를 나타낼 수 있는 배열을 만들고
X배열을 탐색하면서 각 자리 숫자를 배열의 인덱스로 카운트한다.

이후 Y를 탐색하면서 만약 배열의 인덱스값이 0보다 크다면
X배열에서 한번 탐색한 숫자이므로 해당 숫자를 ArrayList에 add한다.

이후 조건을 분기해서 리스트가 비어있다면 -1를 리턴하고,
내림차순 정렬 이후에도 맨 앞에 있는 숫자가 0이라면 해당 배열은
0이 가장 큰 숫자이므로 0을 리턴한다.

이후 StringBuilder를 사용해서 리스트에 있는 값들을 붙여주고 출력한다.

처음에 직관적으로 떠오른 풀이로 해결을 하지 못 해서 한참 고민했다.
이 문제는 문자열로 보는 것이 아닌, 0~9까지의 숫자로 접근해서 풀어야
시간을 줄일 수 있는 문제이다.

처음 생각한 풀이가 답이 아니면 빨리 그 틀에서 벗어나서 새로운 시각에서
풀이를 생각하는 습관을 들여야겠다.

profile
어제보다 성장하는 개발자

0개의 댓글