CodeKata Week 2

Seob·2020년 8월 16일
0

Algorithms

목록 보기
4/8
post-thumbnail

문제 Day 1

로마자에서 숫자로 바꾸기

1~3999 사이의 로마자 s를 인자로 주면 그에 해당하는 숫자를 반환해주세요.
로마 숫자를 숫자로 표기하면 다음과 같습니다.

Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

로마자를 숫자로 읽는 방법은 로마자를 왼쪽부터 차례대로 더하면 됩니다.
III = 3
XII = 12
XXVII = 27
입니다.

그런데 4를 표현할 때는 IIII가 아니라 IV 입니다.
뒤의 숫자에서 앞의 숫자를 빼주면 됩니다.
9는 IX입니다.

I는 V와 X앞에 와서 4, 9
X는 L, C앞에 와서 40, 90
C는 D, M앞에 와서 400, 900 

My Solution

function romanToNum(s) {
const obj = {
  I: 1,
  V: 5,
  X: 10,
  L: 50,
  C: 100,
  D: 500,
  M: 1000
};
  const arr = s.split('');
  console.log(arr)
  return arr.reduce((acc, item, index) => {
    const curVal = obj[item];
    const nextVal = obj[arr[index + 1]];
    if (nextVal > curVal) {
        acc -= curVal;
    }else{
        acc += curVal;
    }
    console.log(acc)
    return acc;
  }, 0);
};

Model Solution

function romanToNum(s) {
  let matching = {
      I: 1,
      V: 5,
      X: 10,
      L: 50,
      C: 100,
      D: 500,
      M: 1000
  }
  
  let strArr = s.split('');
  let numArr = strArr.map(el => matching[el]);
  let sum = 0;
  
  for (let i = 0; i < numArr.length; i++) {
      if (numArr[i] < numArr[i+1]) {
          sum += (numArr[i+1] - numArr[i]);
          i++;
      } else {
          sum += numArr[i];
      }
  }
  
  return sum;
}

문제 Day 2

숫자로 이루어진 배열인 nums를 인자로 전달합니다.
숫자중에서 과반수(majority, more than a half)가 넘은 숫자를 반환해주세요.

예를 들어,

nums = [3,2,3]
return 3
nums = [2,2,1,1,1,2,2]
return 2
  • 가정
    nums 배열의 길이는 무조건 2개 이상

My Solution

function moreThanHalf(nums) {
  let num = 0
  let obj = {}
  const len = Math.floor(nums.length/2)
  for (i in nums) {
    obj[nums[i]] === undefined? obj[nums[i]] = 1 : obj[nums[i]]+=1
  }
  const keys = Object.keys(obj);
  for (j in keys) {
    if (obj[keys[j]] > len) {
      return parseInt(keys[j])
    }
  }
}

Model Solution

function moreThanHalf(nums) {
  let result;
  
  for (let i = 0; i < nums.length; i++) {
    let sum = 0;
    
    for (let j = 0; j < nums.length; j++ ) {
      if (nums[i] === nums[j]) {
        sum += 1;
      }
    }
    
    if (sum > nums.length/2) {
      return nums[i];
    }
  }
}

// or

// function moreThanHalf(nums) {
//   let obj = {};
//   let key = '';
//   let count = nums.length/2;
  
//   for (let i = 0; i < nums.length; i++) {
//       let thisNum = nums[i];
      
//       if (obj[thisNum]) {
//           obj[thisNum]++;
//       } else {
//           obj[thisNum] = 1;
//       }
      
//       if (obj[thisNum] > count) {
//           key = thisNum;
//           break;
//       }
//   }    
  
//   return Number(key);
// }

문제 Day 3

s는 여러 괄호들로 이루어진 String 인자입니다.
s가 유효한 표현인지 아닌지 true/false로 반환해주세요.

종류는 '(', ')', '[', ']', '{', '}' 으로 총 6개 있습니다.
아래의 경우 유효합니다.
한 번 괄호를 시작했으면, 같은 괄호로 끝내야 한다.
괄호 순서가 맞아야 한다.

예를 들어 아래와 같습니다.

s = "()"
return true
s = "()[]{}"
return true
s = "(]"
return false
s = "([)]"
return false
s = "{[]}"
return true

My Solution

function isValid(s) {
  let answer = true;
  let arr = [];
  let map = {
    '(':')',
    '[':']',
    '{':'}',
  }
  for (i in s) {
    if(s[i]==="(" || s[i]==="[" || s[i]==="{"){
      arr.push(s[i]);
    } else if (s[i]===")" || s[i]==="]" || s[i]==="}") {
      var s_key = arr.pop();
      if(s[i]!==map[s_key]){
        return false;
      }
    }
  }if(arr.length!==0){
    answer = false;
}
  return answer;
}

Model Solution


//isValid 함수 설명 37번째줄부터 되어있습니다.
//확인해보세요!
function isValid(s) {
  let matching = {
      '(': ')',
      '[': ']',
      '{': '}'
  };

  let closeArr = [];
  let openArr = [];
  let sArr = s.split('');
  let result = true;

  for (let i = 0; i < sArr.length; i++) {
      let thisStr = sArr[i];
      let closeForOpen = matching[thisStr];
      if (closeForOpen) {
        openArr.push(thisStr);
        closeArr.unshift(closeForOpen);
      } 
      else {
        if (thisStr === closeArr[0]) {
          closeArr.shift();
          openArr.pop();
        } else {
          result = false;
          break;
        }
      }
  }
  
  return result && closeArr.length === 0;
}



//s가 '({})' 라고 가정하겠습니다.
function isValidForCommnet(s) {
  let matching = {
      '(': ')',
      '[': ']',
      '{': '}'
  };

  let closeArr = [];
  let openArr = [];
  let sArr = s.split('');
  let result = true;
  
  //sArr = ['(', '{', '}', ')'] 입니다.
  //sArr을 for문 돌리면서 
  //시작괄호는 openArr에 넣어주고,  ex) openArr = ['(', '{']
  //끝 괄호는 closeArr에 넣어서,    ex) closeArr = ['}', ')']
  //openArr 마지막번째 괄호가 closeArr의 첫번째괄호랑 맞아야 된다는걸 확인하면 됩니다.
  for (let i = 0; i < sArr.length; i++) {
      let thisStr = sArr[i];
      
      //이번 순서의 괄호(thisStr)가 
      //시작괄호-(,[,{- 이라면, matching에 key로 존재하니까
      //closeForOpen가 ) or ] or } 일것이고,
      //끝 괄호라면 undefined 이겠죠.
      let closeForOpen = matching[thisStr];
      
      //thisStr가 시작괄호여서 closeForOpen가 존재한다면,
      if (closeForOpen) {
        
        //openArr에 하나씩 push합니다.
        openArr.push(thisStr);
        //closeArr에는 앞쪽에서 unshift합니다. 
        closeArr.unshift(closeForOpen);
        
      } 
      //closeForOpen가 존재하지 않는다는 뜻은 thisStr가 끝괄호라는 뜻
      else {
        //이번 괄호인 thisStr가 끝괄호면 closeArr에 무조건 첫 번째에 있어야 합니다.
        if (thisStr === closeArr[0]) {
          //제대로 괄호가 여닫기 됐으므로, 
          //closeArr의 첫번째 요소를 제거해주고
          //해당 끝괄호랑 매치되는 openArr의 첫 요소도 제거해줍니다.
          closeArr.shift();
          openArr.pop();
        } else {
          //thisStr가 끝괄호인데, 
          //closeArr의 첫 번째 요소에 있지 않다는 뜻은 제대로 여닫기가 안 된 것이므로
          //for문을 break로 끝내줍니다.
          result = false;
          break;
        }
      }
  }
  
  return result && closeArr.length === 0;
}

문제 Day 4

nums는 숫자로 이루어진 배열입니다.
가장 자주 등장한 숫자를 k 개수만큼 return해주세요.

nums = [1,1,1,2,2,3],
k = 2

return [1,2]
nums = [1]
k = 1

return [1]

My Solution

function topK(nums, k) {
  let obj = {};
  let arr = [];
  let answer = [];
  for (i in nums) {
    obj[nums[i]] ? obj[nums[i]]+=1 : obj[nums[i]]=1
  }
  for (j in obj) {
    arr.push([j,obj[j]]);
  }
  arr.sort((a,b)=>b[1]-a[1])
  for (a=0; a< k; a++){
    answer.push(parseInt(arr[a][0]))
  }
  return answer
}

Model Solution

function topK(nums, k) {
    let obj = {};
    let arr = [];
    
    nums.forEach(el => {
        if (obj[el]) {
            obj[el]++;
        } else {
            obj[el] = 1;
        }
    });
    
    for (let properyName in obj) {
        arr.push([properyName, obj[properyName]]);
    }
    
    return arr.sort((a, b) => (b[1] - a[1])).slice(0,k).map(el => Number(el[0]));
}

topK([1,2,2,2,3,4,4,4,4] , 2);

문제 Day 5

인자인 height는 숫자로 이루어진 배열입니다.
그래프로 생각한다면 y축의 값이고, 높이 값을 갖고 있습니다.

아래의 그래프라면 height 배열은 [1, 8, 6, 2, 5, 4, 8, 3, 7] 입니다.

저 그래프에 물을 담는다고 생각하고,
물을 담을 수 있는 가장 넓은 면적의 값을 반환해주세요.

  • 가정
    배열의 길이는 2이상입니다.

My Solution

function getMaxArea(height) {
  let answer = 0;
  let y = 0;
  let x = 0;
  
  for (i in height) {
    for (j=1; j<height.length; j++) {
      height[i] < height[j] ? y = height[i] : y = height[j]
      x = Math.abs(i-j)
      answer < y*x ? answer = y*x : answer
    }
  }
  return answer
}

Model Solution

function getMaxArea(height) {
    let size = 0;
    
    for (let i = 0; i < height.length; i++) {
        for (let j = i+1; j < height.length; j++) {
            size = Math.max(Math.min(height[i], height[j]) * (j-i), size);
        }
    }
    
    return size;
}
profile
Hello, world!

0개의 댓글