문제

Given an integer n, return a counter function. This counter function initially returns n and then returns 1 more than the previous value every subsequent time it is called (n, n + 1, n + 2, etc).

https://leetcode.com/problems/counter/

 

예시

n이 10일 때, 처음 counter() 메소드를 호출하면 10이 나오고, 또 counter() 메소드를 호출하면 11이 나오고, 또 counter() 메소드를 호출하면 12가 출력된다. 

 

n이 -2일 때 counter()를 5번 호출하면 -2, -1, 0, 1, 2가 출력된다.

 

코드

function createCounter(n: number): () => number {
    return function() {
        return n++;
    }
}


/** 
 * const counter = createCounter(10)
 * counter() // 10
 * counter() // 11
 * counter() // 12
 */

createCounter의 인수로 n이 들어오고, createCounter는 함수를 리턴한다. 리턴된 함수가 counter 변수에 담긴다.

counter 함수가 호출될 때마다 n을 증가시켜야 하므로, n을 증가시키는 코드가 필요하다. 처음 호출될 때는 n이 출력되어야 하므로, n++로 후위 증감 연산자를 이용한다.

728x90

문제

You are given two strings word1 and word2. Merge the strings by adding letters in alternating order, starting with word1. If a string is longer than the other, append the additional letters onto the end of the merged string.

Return the merged string.

https://leetcode.com/problems/merge-strings-alternately/

 

예시

word1부터 번갈아가면서 string을 합쳐주면 된다. 이때, 더이상 번갈아 합칠 수 없으면, 긴 string의 나머지 부분은 그대로 더해진다.


코드

/**
 * @param {string} word1
 * @param {string} word2
 * @return {string}
 */
var mergeAlternately = function(word1, word2) {
    let words = "";

    const minLen = Math.min(word1.length, word2.length);

    // minLen 만큼은 번갈아 가면서
    for(let i = 0; i < minLen; i++){
        words += word1[i] + word2[i];
    }

    // 나머지 긴 string은 붙이기
    words += word1.length > word2.length ? word1.slice(minLen) : word2.slice(minLen);

    return words;

};

word1과 word2 중 짧은 길이만큼 번갈아서 더해주었다.

그 후, word1과 word2 중 더 긴 길이를 가진 string의 남은 부분을 더해주었다.

Array.prototype.slice() 를 사용하면 배열의 원하는 인덱스부터 끝까지 자를 수 있다.

 

728x90

문제

https://school.programmers.co.kr/learn/courses/30/lessons/77884?language=javascript 

 

입출력

 


코드

function solution(left, right) {
    let answer = 0; 
    // left 부터 right 까지의 수들의 약수 개수 구하기
    for(let i = left; i <= right; i++){
        let count = 0; // i의 약수 개수를 저장
        
        // j는 1부터 i의 제곱근까지의 수
        // j가 i의 약수인지 확인
        for(let j = 1; j <= Math.sqrt(i); j++){
            if(i % j === 0) { // i가 j로 나누어 떨어지면 약수이다.
                count++;
                if(i / j != j) count++; // i = 25, j = 5의 경우 5를 2번 세면 안됨.
            }
        }
        // 약수의 개수가 짝수면 더하고 홀수면 빼기
        count % 2 === 0 ? answer += i : answer -= i;
    }
    return answer;
}

 

풀이

left와 right 사이에 있는 수들의 약수 개수를 구하고, 그 개수가 짝수면 더하고 홀수면 빼면 된다.

 

1. 반복문으로 left에서 right까지 돌면서 i의 약수 개수를 구해준다. count는 i의 약수 개수를 저장할 변수이다.

2. j를 1부터 i의 제곱근까지 확인하면서 i의 약수인지 확인하고, i가 j로 나누어 떨어지면 약수이므로 count++ 해준다.

이때, i의 끝까지 확인하는 것이 아니라 i의 제곱근까지만 확인하는 이유는 굳이 끝까지 확인하지 않아도 되기 때문이다. 물론 다 확인해서 약수를 구해도 답을 구할 수 있다.

 

예를 들어, i = 25라고 해보자.

25의 약수는 1 5 25 이다.

 

방법 1) 1부터 끝까지 확인하는 방법

1부터 25까지 돌면서 25 % 1 === 0 , 25 % 2 === 0, ... 25 % 25 === 0 을 확인해 count++를 해준다.

-> 3개가 나온다.

 

방법 2) 1부터 i의 제곱근인 5까지 확인하는 방법(에라토스테네스의 체)

25 % 1 === 0, 25 % 2 === 0, 25 % 3 === 0, 25 % 4 === 0, 25 % 5 === 0 을 확인한다.

나누어 떨어진다면 i의 약수이다. 그러나 제곱근까지만 확인했기 때문에 count를 한 번 더 세주어야한다. 1 x 25 = 25이므로, 1도 25의 약수이고 25도 25의 약수가 된다. 따라서 1을 세줄 때, 25도 같이 세어주어야한다.

5가 약수인지 판단했을 때, 25 % 5 는 0이어서 약수로 판명이 된다. 

이때 5의 경우에는 한 번만 세주어야 하므로(5 x 5 = 25), i / 5 == 5 인 경우에는 세어주면 안된다.

따라서 i / j != j 인 경우에만 count를 한 번 더 세어주었다. i != j * j 와 같은 식이다.

 

구한 i의 약수의 개수가 짝수면 answer에 더해주고, 홀수면 빼주었다. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90

문제

https://school.programmers.co.kr/learn/courses/30/lessons/42748

 

코드

function solution(array, commands) {
    const answer = []; // 결과를 저장할 배열

        // commands 를 돌며 각 경우의 값을 구한다.
    for(let i = 0; i < commands.length; i++){
        const arr = array.slice(commands[i][0]-1, commands[i][1]).sort((a,b)=>a-b);
        answer.push(arr[commands[i][2]-1]);
    }

    return answer;
}

 

해설

입력으로 들어오는 array를 조건에 맞게 잘라 원하는 인덱스의 값을 반환하는 문제이다.

js의 Array.prototype.slice() 를 이용하면 쉽게 구할 수 있다.

command[i][0]-1은 begin, command[i][1]은 end가 된다. 배열은 0번째 인덱스 부터 시작하지만, 문제에서는 1부터 시작이기 때문에, 배열의 인덱스로 맞추어 주려면 1을 빼주어야한다.

 

command[i][1]의 경우는 1을 빼주지 않아도 된다. 왜냐하면 slice 함수는 end-1 인덱스 까지 잘라주기 때문이다.

그 후 sort 함수를 이용해서 자른 배열을 정렬시켜주었다. 람다 함수를 이용해서 오름차순 정렬을 해주었는데, 따로 정렬 조건을 부여하지 않으면 원하는 대로 정렬이 되지 않을 수 있다.

 

js는 오름차순 정렬을 위해 그냥 sort() 만 사용하면 [10,9]를 정렬할 경우 [10,9] 로 정렬이된다. 원하는 결과인 [9,10] 과 다르게 나온다. 그 이유는 처음 앞 숫자인 1과 9를 비교했을 때 9가 크기 때문이다. 따라서 원하는 대로 정렬을 하려면 정렬 조건을 부여해주는 것이 좋다.

 

정렬이 완료되었다면, command[i][2]번째 인덱스를 구헤야한다. 그러나 위에서 말했듯이, 문제에서는 1부터 시작하지만 배열은 0번째 인덱스부터 시작하므로 우리가 만든 배열에 대입하기 위해서는 1을 빼주어야한다.


* Array.prototype.slice()

배열명.slice([begin[, end]])

배열의 begin 인덱스부터 end-1 인덱스까지 잘라서 반환한다.

const arr = [1,2,3,4,5]

// begin & end를 모두 입력받는 경우
// begin 부터 end-1 인덱스까지 잘라 반환
console.log(arr.slice(1,3)) // [2,3]

// begin 만 입력 받는 경우
// array[begin]부터 array의 끝까지 잘라 반환
console.log(arr.slice(3)) // [3,4,5]

// 아무것도 입력하지 않는 경우
// array 그대로 반환
console.log(arr.slice()) // [1,2,3,4,5]

 

* Array.prototype.sort()

배열명.sort([compareFunction])

const arr = [8,9,10]

// sort()만 사용하는 경우
console.log(arr.sort()) // [10,8,9]

// 오름차순 정렬
console.log(arr.sort((a,b)=>a-b)) // [8,9,10]

// 내림차순 정렬
console.log(arr.sort((a,b)=>b-a)) // [10,9,8]
728x90

+ Recent posts