문제 설명
: 두 자연수 a와 b가 주어질 때, 이 둘의 최대공약수를 구하는 함수를 작성하세요.
문제 풀이
최대 공약수는 서로 나누어떨어지는 수를 구하고, 나누어 떨어지지 않을때까지 반복하면 된다.
하지만 반복을 언제까지 하느냐? 이 부분을 처리하는 것이 관건이었다.
약수를 구할 때, 자연수 x가 자연수 n에 의해 나누어 떨어진다고 가정하면 나눈 n 값과 나누어진 x의 값이 약수가 된다.
이렇게 나눈 값과 나누어진 값이 페어로 약수가 되는 점을 고려하면 나눈 값은 자연수 x의 제곱근보다 작을 수 밖에 없다는 것이 특징이 된다.
이 점을 고려해서 반복문을 자연수 x가 주어질 때 x의 제곱근만큼만 반복하도록 설정하였다.
전체 코드
function getCommonDivisor(a, b) {
let min = Math.min(a, b);
let max = Math.max(a, b);
let res = 1;
let i;
for(let i=2; i<=Math.sqrt(max); i++) {
while(max%i === 0 && min%i === 0) {
res *= i;
max /= i;
min /= i;
}
}
return res;
}
문제 설명
주어진 배열에서 짝수와 홀수의 개수를 각각 세는 함수를 작성하세요. 함수는 [짝수 개수, 홀수 개수]의 배열을 반환해야 합니다.
문제 풀이
주어진 배열을 반복하여 2로 나누어 떨어지는지 확인하고 짝수와 홀수 개수를 카운트했다.
전체 코드
function countEvenAndOdd(arr) {
const answer = [0, 0];
for(let i=0; i<arr.length; i++) {
// 짝수
if(arr[i] % 2===0) {
answer[0]++;
}
else if(arr[i] %2 !== 0) {
answer[1]++;
}
}
return answer;
}
문제 설명
문자열이 주어지면 해당 문자열을 역순으로 배치한 후, 알파벳을 하나씩 오른쪽으로 이동시킨 결과를 출력하세요. 예를 들어, a는 b, z는 a로 변환됩니다.
문제 풀이
역순으로 배치는 reverse()를 주었고, str이 문자열이기 때문에 reverse 메서드를 사용하기 위해 split 메서드로 배열로 바꾸어 주었다.
하나씩 오른쪽으로 이동 시키는 것은 각 문자를 ASCII 코드 10진수로 변환하여 증감해주는 방식으로 구현했다.
전체 코드
function reverseAndShift(str) {
let tempStr = str.split('').reverse();
console.log(tempStr);
for(let i=0; i<tempStr.length; i++) {
let transformChar = tempStr[i].charCodeAt(0);
transformChar++;
if(transformChar >= 122) {
transformChar = 97;
}
tempStr[i] = String.fromCharCode(transformChar);
}
return tempStr.join('');
}
문제 설명
회전 초밥을 먹을 때, 접시들의 번호가 주어집니다.
이 중에서 임의의 연속된 접시를 선택하여 먹을 때, 가능한 모든 선택에서 가장 다양한 초밥 종류의 개수를 구하세요.
문제 풀이
Set 자료구조는 고유의 값을 저장하는 특징이 있다.
중복된 값이 들어와도 고유의 개수를 유지하기 때문에 Set 자료구조를 활용해서 구현했다.
전체 코드
function countDistinctMeals(arr) {
let temp = new Set();
for(let i=0; i<arr.length; i++) {
temp.add(arr[i]);
}
return temp.size;
}
문제 설명
양의 정수가 주어질 때, 숫자에서 k개의 자릿수를 제거하여 얻을 수 있는 가장 큰 수를 구하세요.
문제 풀이
전체 코드
function getMaxNumber(num, k) {
const numToArr = num.toString().split('').sort((a,b) => {return b-a;});
for(let i=0; i<k; i++) {
numToArr.pop();
}
console.log(numToArr.join(''));
}
문제 설명
주어진 문자열에서 중복된 문자를 제거하고, 남은 문자들을 원래 순서대로 반환하는 함수를 작성하세요.
ex) [a,b,c,d,a,b] => [a,b,c,d] 출력
문제 풀이
이 문제도 Set 자료구조를 사용했다.
사실 처음에 예시 출력이 없어서 중복된다면 모두 삭제하도록 했었는데 기존 값은 그대로 두고 이후 중복값만 제거하는 형식이어서 쉽게 구현했다.
전체 코드
function deleteDistinctStr(str) {
const mySet = new Set();
for(idx in str) {
mySet.add(str[idx]);
}
return [...mySet].join('');
}
문제 설명
주어진 배열에서 최솟값과 최댓값을 찾고, [최솟값, 최댓값] 형태의 배열을 반환하는 함수를 작성하세요.
문제 풀이
배열 안에서의 최솟값 최댓값을 구하는 것이다.
각자 값을 저장할 변수가 있어야겠다고 생각했고, 해당 값에 최소,최대 값을 찾으려면 Math.min(), Math.max() 메서드를 사용해야 한다는 것이 떠올랐다.
mix() max() 메서드의 경우 파라미터로 숫자들을 전달 받는다.
즉, 배열 형태인(arr)로 받아버리게 되면 안되고 Spread Operator 를 사용하면 arr에 담긴 값들을 배열이 아닌 분해된 상태로 매개변수를 입력할 수 있다.
전체 코드
function getMinMax(arr) {
let res=[];
res[0] = Math.min(...arr);
res[1] = Math.max(...arr);
return res;
}
문제 설명
주어진 문자열을 요약하는 함수를 작성해주세요!
ex) 'aaabbccc' 입력 -> 'a3/b2/c3' 출력
문제 풀이
다른 종류의 값들을 카운트하는 방식은 뭘 쓰면 좋을까 하다가 객체를 떠올리게 되었다.
객체는 key:value 형태로 되어있기 때문에 만약 'aabbc' 가 주어진다면 'a' 알파벳의 키에 count값, 'b' 알파벳의 키에 count값, ... 이런식으로 주면 좋을 것 같았다.
그렇게 주어진 값은 템플릿 리터럴 방식을 통해 끝나는 곳에 '/' 를 붙여 res에 추가하는 방향으로 하였다.
마지막에 '/'는 없으니 slice 메서드를 통해 없애주었다.
전체 코드
function summationStr(str) {
let distinctStr = {};
let res='';
for(let i = 0; i < str.length; i++) {
if(distinctStr[str[i]] !== undefined) {
distinctStr[str[i]]++;
}
else {
distinctStr[str[i]] = 1;
}
}
for(key in distinctStr) {
res += `${key}${distinctStr[key]}/`;
}
res = res.slice(0, res.length-1);
return res;
}
문제 설명
주어진 배열에서 두 수를 선택하여 그 합이 주어진 target 값과 일치하는지 확인하는 함수를 작성하세요. 일치하는 경우 true, 그렇지 않은 경우 false를 반환하세요.
문제 풀이
전체 코드
function findPlusTarget(arr, target) {
const findArr = [];
for(idx in arr) {
if (arr[idx] < target) {
findArr.push(arr[idx]);
}
}
for(idx_first in findArr) {
for(idx_second in findArr) {
if(findArr[idx_first] + findArr[idx_second] === target) {
return true;
}
}
}
return false;
}
문제 설명
주어진 문자열이 유효한 괄호 조합인지 확인하는 함수를 작성하세요.
유효한 조합은 모든 여는 괄호가 올바르게 닫혀야 하며, 괄호의 순서도 일치해야 합니다.
ex) '{[{[]}]}' 입력 -> true // '{[]])' -> false // '{}[[' -> false
문제 풀이
if(str.length%2 !== 0)
return false;
괄호의 뎁스를 확인하기 위한 stack을 선언하였다. let stack=0;
괄호는 짝꿍이 있다는 점을 생각해서 객체로 묶어보는 방법을 떠올렸다.
const isValidClose = {
')': '(',
'}': '{',
']': '['
}
let myParent = {};
for(idx in str) {
if(str[idx] === '{' || str[idx] === '[' || str[idx] === '(') {
myParent[stack] = str[idx];
stack++;
}
... (다음 로직)
}
5-1. 만약 } or ] or ) 라면 현재 저장된 뎁스의 괄호가 현재 문자의 괄호 열기 문자와 한 쌍인지 확인하는 검증을 하였다.
for(idx in str) {
if(str[idx] === '}' || str[idx] === ']' || str[idx] === ')') {
const matchParent = isValidClose[str[idx]];
if(myParent[stack-1] === matchParent) {
...(5-2 로직)
}
else {
...(5-3 로직)
}
}
}
5-2. 한쌍이라면 저장된 뎁스의 괄호를 delete, stack을 감소
5-3. 아니라면 바로 false를 return 해주었다.
if(stack !== 0) {
return false;
}
전체 코드
function isValidParentheses(str) {
if(str.length%2 !== 0)
return false;
let stack=0;
const isValidClose = {
')': '(',
'}': '{',
']': '['
}
let myParent = {};
for(idx in str) {
if(str[idx] === '{' || str[idx] === '[' || str[idx] === '(') {
myParent[stack] = str[idx];
stack++;
}
if(str[idx] === '}' || str[idx] === ']' || str[idx] === ')') {
const matchParent = isValidClose[str[idx]];
if(myParent[stack-1] === matchParent) {
delete myParent.stack;
stack--;
}
else {
return false;
}
}
}
if(stack !== 0) {
return false;
}
return true;
}