개발조각

[리트코드] 12. Integer to Roman 본문

알고리즘🅰/리트코드

[리트코드] 12. Integer to Roman

개발조각 2022. 9. 13. 21:12
728x90
반응형

안녕하세요. 개발조각입니다.😊

이번 문제는 어려운 건 아닌데... 머리를 굴려야 해결할 수 있어서 푸는데 좀 오래 걸렸어요ㅠ


https://leetcode.com/problems/integer-to-roman/submissions/

 

Integer to Roman - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

해결방안

var intToRoman = function(num) {
    let roma = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'};
    let romaNum = '';
    
    let strArr = String(num).split('');
    let numArr = strArr.map((x, i)=> parseInt(x)*(10**(strArr.length-i-1))).reverse(); 
    
    console.log(numArr)
    for(let i=0; i<numArr.length; i++){
        let num = numArr[i];
        let isRoma = roma[num];
        
        if(isRoma) romaNum = isRoma+romaNum;
        else{
            let str = '';        
            let [one, five, ten] = [i ? 10**(i-1)*10 : 1, 10**(i)*5, 10**(i+1)]
            let [roma1, roma5, roma10] = [roma[one], roma[five], roma[ten]];
            
            if(ten-num === 10**i) str = roma1+roma10;
            else if(num-five === -(10**i)) str = roma1+roma5;
            else if(num > five){
                let remainder = (num - five)/one;
                str = roma5+roma1.repeat(remainder);
            }
            else if(num < five){
                let remainder = num/one;
                str = roma1.repeat(remainder);
            }            
            romaNum = str+romaNum;
        }
    }
    return romaNum;
};

기존에 생각했던 해결방안입니다.

 

let roma = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'};

먼저 1, 5, 10, 50, 100, 500, 1000에 대한 각각에 해당되는 로마 숫자를 대입해주었습니다.

 

let strArr = String(num).split('');
let numArr = strArr.map((x, i)=> parseInt(x)*(10**(strArr.length-i-1))).reverse();

만약 num = 1994 일 경우 numArr = [4, 90, 900, 1000]으로 바꾸면 뒤에 반복문 돌리면서

각각의 로마 숫자 구하기 쉬워질 것 같아서 바꾸어 보았습니다.

 

let num = numArr[i];
let isRoma = roma[num];

if(isRoma) romaNum += isRoma;

roma배열에 있는 숫자인 경우에 대한 코드입니다.

isRoma는 roma객체에 해당하는 값이 있으면 로마 숫자로 반환해 줍니다.

 

else{
    let str = '';        
    let [one, five, ten] = [i ? 10**(i-1)*10 : 1, 10**(i)*5, 10**(i+1)]
    let [roma1, roma5, roma10] = [roma[one], roma[five], roma[ten]];

    if(ten-num === 10**i) str = roma1+roma10;
    else if(num-five === -(10**i)) str = roma1+roma5;
    else if(num > five){
        let remainder = (num - five)/one;
        str = roma5+roma1.repeat(remainder);
    }
    else if(num < five){
        let remainder = num/one;
        str = roma1.repeat(remainder);
    }            
    romaNum = str+romaNum;
}

roma배열에 있는 숫자가 아닌 다른 숫자일 경우에 대한 코드입니다.

여기서는 4가지로 구분하였습니다.

  • 9, 90, 900일 경우
  • 4, 40, 400일 경우
  • 6~8, 60~80, 600~800일 경우
  • 1~3, 10~30, 100~300일 경우

4가지는 if else로 구하였습니다.

 

let [one, five, ten] = [i ? 10**(i-1)*10 : 1, 10**(i)*5, 10**(i+1)]
let [roma1, roma5, roma10] = [roma[one], roma[five], roma[ten]];

one, five, ten은 해당 위치에 가까운 숫자? 라 해야 될까요.

만약 num=30이면 one=10, five=50, ten=100이 됩니다.

one에서는 만약 num이 한자리 수면 1을 반완해야 되기 때문에 삼항 연산자로 해주었습니다.

 

roma1, roma5, roma10은 위에 one, five, ten의 값에 대한 로마 숫자입니다.


이렇게 

  • 9, 90, 900일 경우
  • 4, 40, 400일 경우

이 2가지를 각각 다 구해도 되지만 roma배열에 미리 써두는 것도 좋은 방법입니다.

let roma = {1:'I', 4:'IV', 5:'V', 9:'IX', 10:'X', 40:'XL', 50:'L', 90:'XC', 100:'C', 400:'CD', 500:'D', 900:'CM', 1000:'M'};

이렇게요.

 

위와 같이 roma배열에 더 추가할 경우 바뀐 코드입니다.

var intToRoman = function(num) {    
    let roma = {1:'I', 4:'IV', 5:'V', 9:'IX', 10:'X', 40:'XL', 50:'L', 90:'XC', 100:'C', 400:'CD', 500:'D', 900:'CM', 1000:'M'};
    let romaNum = '';
    
    let strArr = String(num).split('');
    let numArr = strArr.map((x, i)=> parseInt(x)*(10**(strArr.length-i-1))).reverse(); 
    
    for(let i=0; i<numArr.length; i++){
        let num = numArr[i];
        let isRoma = roma[num];
        
        if(isRoma) romaNum = isRoma+romaNum;
        else{
            let str = '';        
            let [one, five] = [i ? 10**(i-1)*10 : 1, 10**(i)*5];
            let [roma1, roma5] = [roma[one], roma[five]];
            
            if(num > five){
                let remainder = (num - five)/one;
                str = roma5+roma1.repeat(remainder);
            }
            else if(num < five){
                let remainder = num/one;
                str = roma1.repeat(remainder);
            }            
            romaNum = str+romaNum;
        }
    }
    return romaNum;
};

이렇게 되면

 

if(ten-num === 10**i) str = roma1+roma10;
else if(num-five === -(10**i)) str = roma1+roma5;

 이걸 안 써도 되고

let [one, five, ten] = [i ? 10**(i-1)*10 : 1, 10**(i)*5, 10**(i+1)]
let [roma1, roma5, roma10] = [roma[one], roma[five], roma[ten]];

ten, roma10도 필요 없게 됩니다.

 

728x90
반응형
Comments