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

상현·2023년 11월 22일
2

코딩테스트

목록 보기
21/30
post-thumbnail

[level 1] 숫자 짝꿍 - 131128

문제 링크

성능 요약

메모리: 33.5 MB, 시간: 0.24 ms

구분

코딩테스트 연습 > 연습문제

채점결과

정확성: 100.0
합계: 100.0 / 100.0

제출 일자

2023년 11월 3일 9:59:38

문제 설명

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

예를 들어, X = 3403이고 Y = 13203이라면, XY의 짝꿍은 XY에서 공통으로 나타나는 3, 0, 3으로 만들 수 있는 가장 큰 정수인 330입니다. 다른 예시로 X = 5525이고 Y = 1255이면 XY의 짝꿍은 XY에서 공통으로 나타나는 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

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

출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges

처음 시도

function solution(X, Y) {
    let common = [];
    let longger = X.length > Y.length ? [...X] : [...Y];
    let shorter = X.length > Y.length ? [...Y] : [...X];
    
    for (let i = 0; i < shorter.length; i++) {
        const c = shorter[i];
        let index = longger.indexOf(c);
        if (index !== -1) {
            common.push(c);
            longger.splice(index, 1);
        }
    }

    if (common.length === 0) return "-1";

    common.sort((a, b) => +b - +a);
    if (common[0] === '0') return "0"
    return common.join("");
}

처음 시도는 중복을 제거하기 위해 기존 배열을 splice를 통해 제거하면서 진행했다. 로직은 맞지만, 시간 초과가 떠서 실패했다.

최종 제출

function solution(X, Y) {
    let xArray = new Array(10).fill(0);
    let yArray = new Array(10).fill(0);
    
    [...X].forEach(c => xArray[c]++);
    [...Y].forEach(c => yArray[c]++);
    
    let answer = '';
    for (let i = 9; i >= 0; i--) {
        let x = xArray[i];
        let y = yArray[i];
        if (x > 0 && y > 0) answer += (`${i}`.repeat(Math.min(x, y)))
        
    }
    if (answer === "") return "-1";
    if (answer[0] === '0') return "0";
    return answer;
}

새로 푼 풀이 로직은 다음과 같다.

  1. 0~9의 숫자의 개수를 담는 배열 xArray, yArray 2개를 만든다.
  2. 주어진 배열 X, Y를 각각 돌면서, 자리 수를 담는 배열의 인덱스에 접근하여 카운트를 늘린다.
    (e.g. "13334" => [0, 1, 0, 3, 1, 0, 0, 0, 0, 0]
    즉, 1은 1개, 3은 3개, 4는 1개라는 뜻이다.
  3. 9부터 0까지 거꾸로 돈다. 거꾸로 돌면 큰 수부터 찾게 되므로, 자동으로 가장 큰 수를 찾게 된다.
  4. 동일 인덱스에서 xArray에 담긴 값과 yArray의 담긴 값을 비교하여 더 작은 값을 i만큼 반복해서 넣는다. 그 이유는 예를 들어, X = "5525", Y = "1255" 일 때, xArray = [0, 0, 1, 0, 0, 3, 0, 0, 0, 0] yArray = [0, 1, 1, 0, 2, 0, 0, 0, 0, 0]가 된다.
    즉, 공통 되는 부분은 "552" 이고, 더 작은 값이 아니라 큰 값을 넣게 될 경우 중복된 값이 들어가서 "5552"가 되버리기 때문이다.

오늘도 새로운 풀이 방법을 알았다..!!

profile
프론트엔드 개발자 🧑🏻‍💻 https://until.blog/@love

1개의 댓글

comment-user-thumbnail
2023년 11월 22일

안녕하세요 :) 국비지원 부트캠프 엘리스트랙입니다! 오늘도 개발 공부 열심히 하고 계시군요! 멋지십니다 :)
혹시 신입으로 개발 공부하면서 기술면접에 대한 대비가 막막하시다면, 이번 기술면접 특강도 관심 가져보시면 좋을 것 같아 댓글로 행사 안내드려요~

프론트/ 백엔드 모두 실력있고, 실제 면접관으로 활동하고 계신 개발자 코치님께서 진행하시니 참여해 보세요> https://festa.io/events/4389

그럼 오늘도 화이팅입니다!🙇🏻‍♀️💪🏻

답글 달기