[Java] 프로그래머스 숫자 짝꿍

2025. 11. 1. 08:58알고리즘

728x90
반응형

문제 설명

두 정수 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의 짝꿍은 상당히 큰 정수일 수 있으므로, 문자열로 반환합니다.

Psedo Code

for 문자열 X
  if Y에 X의 문자 a가 있다면
	리스트에 문자 a 추가
	문자열 Y에서 처음 발견되는 a 지움
리스트가 비어있으면 -1
리스트 내림차순으로 변경
처음이 0이면 0리턴 아니면 값 리턴

 

작성한 코드 

테스트 통과, 시간 초과 코드

import java.util.*;
import java.util.stream.*;
class Solution {
    public String solution(String X, String Y) {
        List<Character> list = new ArrayList<>();
        int lenX = X.length();
        for(int i = 0 ; i < lenX ; i++) {
            if(Y.contains(String.valueOf(X.charAt(i)))) {
                list.add(X.charAt(i));
                Y = Y.replaceFirst(String.valueOf(X.charAt(i)), "");
            }
        }
        if(list.isEmpty()) {
            return "-1";
        }
        list.sort(Collections.reverseOrder());
        String answer = list.stream().map(String::valueOf).collect(Collectors.joining());
        return answer.startsWith("0") ? "0" : answer;
    }
}
  • contains(..) - 문자열 처음부터 끝까지 탐색 (O(|Y|))
  • replaceFirst(..) - 문자열 전체 스캔 (O(|Y|)), String은 불변이기 때문에 매번 새로운 String 객체 생성
  • 이 과정이 lenX만큼 반복
  • 총 시간 복잡도 O(|X| * |Y|)
  • 각X,Y의 자리수가 3,000,000까지 가능하기 때문에 1억번 이상의 탐색 발생

제출한 코드

class Solution {
    public String solution(String X, String Y) {
        Map<Character, Integer> map = new HashMap<>();
        Map<Character, Integer> map2 = new HashMap<>();
        StringBuilder sb = new StringBuilder();

        for(char c : X.toCharArray()) map.put(c, map.getOrDefault(c, 0) + 1);
        for(char c : Y.toCharArray()) map2.put(c, map2.getOrDefault(c, 0) + 1);
        for (char c = '9'; c >= '0'; c--) {
            int common = Math.min(map.getOrDefault(c, 0), map2.getOrDefault(c, 0));
            // common번 만큼 StringBuilder에 append
            sb.append(String.valueOf(c).repeat(common));
        }
        if (sb.length() == 0) return "-1";
        if (sb.charAt(0)== '0') return "0";
        else return sb.toString();
    }
}
  • 각문자열에서 빈도 계산 (O(|X| + |Y|))
  • 공통으로 들어가는 숫자 계산 + append → O(N)
  • 총 시간 복잡도  (O(|X| + |Y|))
728x90
반응형

'알고리즘' 카테고리의 다른 글

[Java] 프로그래머스 햄버거 만들기  (0) 2025.11.04
[Java] 프로그래머스 둘만의 암호  (0) 2025.11.02
[Java] 덧칠하기  (0) 2025.10.19
[Java] 배열 만들기 4  (0) 2025.10.15
[Java] 특별한 이차원 배열1  (0) 2025.10.14