숫자 짝꿍(Javascript)

·2022년 10월 11일
0
post-thumbnail

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

입출력 예

XYresult
"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

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

function solution(X, Y) {
    let arrX = new Map();
    let arrY = new Map();
    let common = new Map();

    for(let i = 0; i< X.length; i++){
        arrX.set(X[i], (arrX.get(X[i])||0) + 1);
    }
    for(let i = 0; i< Y.length; i++){
        arrY.set(Y[i], (arrY.get(Y[i])||0) + 1);
    }    
    for(let [kX,vX] of arrX)
        for(let[kY,vY] of arrY){
            if(kX === kY){
                common.set(kX, vX <= vY ? arrX.get(kX) : arrY.get(kY))
            }
        }

    let str = '';
    if(common.size === 0)
        str = '-1';
    else if([...common].filter(([k,v]) => k != 0).length === 0)
        str = '0';
    else{
        for(let [k,v] of [...common].sort((a,b) => b[0] - a[0])){
            str += k.repeat(v)
        }
    }
    return str;
}

각 X와 Y를 map()에 넣어서 자릿수의 갯수를 세 줬다. 그리고 자릿수의 갯수를 비교한 다음 작은 쪽의 값을 새로운 map()에 넣어 주었다.

그리고 배열이 비었다면 -1을, 전체가 0으로 구성되어있으면 0을, 아니라면 값을 비교하여 큰 순서대로 문자를 합쳐주었다.

참고할 풀이

const solution = (x, y) => {
            let result = '';
            const map = new Map();
            for(let i = 0; i < y.length; i++){
                map.set(y[i], (map.get(y[i]) || 0) + 1);
            }

            for(let i = 0; i < x.length; i++){
                if(map.get(x[i]) >= 1){
                    map.set(x[i], (map.get(x[i]) || 0) -1)
                    result += x[i];
                }
            }

            if(result.length < 1) return '-1';
            return +result === 0 ? '0' : result.split('').sort((a, b) => b - a).join('');
        }

사실 중복되는 부분이 많아서 고민이 많았는데, 중복을 없앤 깔끔한 풀이인 듯 하다. 나는 X와 Y의 각 숫자의 갯수를 다른 map()에 넣어줬는데, 이 풀이에서는 한 개의 map()에 넣어주었다. 처음에 Y의 각 자릿수의 갯수를 센 다음, X의 자릿수의 갯수를 세는데 key값이 하나라도 있으면 비교하는 곳으로 넘어간다. 거기서 숫자를 세 주는데, 이번에는 존재한다면 값을 -1씩 빼주고 key값을 result에 더해 준다.

그래서 빈 배열이라면 -1을 인출한다. 값 전체가 0인 경우는 문자 배열 앞에 +를 넣어 숫자로 형변환 해준 후에 0이면 0을 리턴, 아니라면 문자를 나눈 다음에 정렬해서 다시 문자로 돌려 준다.

시간 초과

function solution(X, Y) {
    let common = new Map();
    let arrY = [...Y]
    let arrX = [...X]
    
    for(let i = 0 ; i< arrX.length; i++){
        for(let j = 0; j< arrY.length; j++){
            if(arrX[i] === arrY[j]){
                common.set(arrX[i], (common.get(arrX[i])||0) + 1);
                arrX.splice(i,1);
                arrY.splice(j,1);
                i--;
                j--;
                break;
            }
        }
    }
    let str = '';
    if(common.size === 0)
        str = '-1';
    else if([...common].filter(([k,v]) => k != 0).length === 0)
        str = '0';
    else{
        for(let [k,v] of [...common].sort((a,b) => b[0] - a[0])){
            str += k.repeat(v)
        }
    }
    return str;
}
function solution(X, Y) {
    let arrX = [...X]
    let arrY = [...Y]
    let common = [];
    
    for(let i = 0; i< arrX.length; i++)
        for(let j = 0; j < arrY.length; j++){
            if(arrX[i] === arrY[j]){
                common.push(arrX[i]);
                arrX.splice(i,1);
                arrY.splice(j,1);
                i--;
                j--;
                break;
            }
        }
        if(common.length === 0)
            return '-1'
        else if(common.filter(v => v != 0).length === 0)
            return '0'
        else
            return common.sort((a,b) => b-a).join('');
}

아무리 break를 걸고 map에 넣어준다고 해도 splice()push()가 들어가는 이상 시간 초과가 난다. 들어올 값이 큰 경우에는 이 함수들을 사용하는 것을 자제해야겠다.

profile
전 이것도 몰라요

0개의 댓글