[문제 링크]

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


[문제 사고]

주어진 배열과 주어진 조건의 순열을 완전 탐색을 통해 비교하면서 일치하는 값을 필터링하여 일치하는 값이 높은 순열에 해당하는 숫자를 도출해낸다.

 

[문제 해결]

1. 각 수포자가 찍는 방식에서 반복되는 부분을 찾아 배열로 선언을 한다.
2. 정답으로 주어진 배열과 찍는 방식이 담긴 배열을 완전 탐색을 통해 filter method를 사용해 일치하는 요소의 개수를 각각 선언한다.
3. 일치하는 요소 개수들 중 최대값을 골라낸다.
4. 최대값이 일치하는 요소 개수와 같은 변수는 결과값이 담길 빈 배열에 수포자의 번호를 push 해준다.
5. 결과값이 담긴 배열을 return한다.

 

[작성 코드]

function solution(answers) {
    const one = [1,2,3,4,5];
    const two = [2,1,2,3,2,4,2,5];
    const three = [3,3,1,1,2,2,4,4,5,5];
    const correctOne = answers.filter((e,i) => e === one[i % one.length]).length;
    const correctTwo = answers.filter((e,i) => e === two[i % two.length]).length;
    const correctThree = answers.filter((e,i) => e === three[i % three.length]).length;
    const max = Math.max(correctOne,correctTwo,correctThree);
    const result = [];
    if(max === correctOne) result.push(1);
    if(max === correctTwo) result.push(2);
    if(max === correctThree) result.push(3);
    return result;
}

 

[문제 회고]

주어진 정답 배열을 갖고 수포자의 찍는 방식이 표현된 순열을 완전 탐색하며 일치하는 값을 찾아내야겠다고 우선적으로 생각이 들기는 했다. 처음에는 수포자의 찍는 방식의 패턴을 찾아내어 빈 배열에 반복문을 통해 주어진 정답 배열의 길이만큼 반복하여 넣으려고 했지만 그럴 필요가 없이 반복되는 부분만 배열을 넣어두고 인덱스 값의 나머지를 통해 순회를 하면 된다는 점을 찾아냈다. 또한 코드의 효율성이 좋지 않아보이고 불필요한 변수 선언이 많아 보이는 경향이 있었지만 런타임 결과는 그닥 나쁘지 않았다. 하지만 변수 선언을 줄여서 메모리를 최적화 할 수 있는 방법이 있는지 생각해 볼 계획이다.

 

[문제 링크]

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


[문제 사고]

이중 배열을 완전 탐색하여 주어진 조건에 충족할 수 있도록 정렬한 후 필요한 요소를 뽑아내어 연산하여 결과를 도출한다.

 

[문제 해결]

<1번 풀이>

1. 가로 길이를 세로 길이보다 큰 수치로 만들어 놓기 위해 이중 배열을 순회하며 오름차순으로 정렬한다.
2. 가로 길이를 넣어둘 배열과 세로 길이를 넣어둘 배열을 생성한다.
3. 정렬한 배열을 순회하며 가로 길이 값들을 가로 배열에, 세로 길이 값들을 세로 배열에 push해준다.
4. 가로,세로 배열을 내림차순으로 정렬한 후 0번째 인덱스 값을 뽑아내어 곱해준다.

<2번 풀이>

1. 가로 길이를 세로 길이보다 큰 수치로 만들어 놓기 위해 이중 배열을 순회하며 오름차순으로 정렬한다.
2. 이중 배열의 0번째 인덱스 값들을 내림차순으로 정렬하여 첫번째 값을 width로 선언한 가로 변수 값에 넣어준다.
3.이중 배열의 1번째 인덱스 값들을 내림차순으로 정렬하여 첫번째 값을 height로 선언한 세로 변수 값에 넣어준다.
4. 가로,세로 값을 곱해준다.

 

[작성 코드]

//1번 풀이
function solution(sizes) {
    const arr = sizes.map(e => e.sort((a,b) => a - b));
    const width = [];
    const height = [];
    arr.map(e => {
        width.push(e[0])
        height.push(e[1])
    })
    return (width.sort((a,b) => b - a))[0] * (height.sort((a,b) => b - a))[0];
}
//2번 풀이
function solution(sizes) {
    const arr = sizes.map(e => e.sort((a,b) => a - b));
    const width = (arr.sort((a,b) => b[0] - a[0]))[0][0];
    const height = (arr.sort((a,b) => b[1] - a[1]))[0][1];
    return width * height;
}

 

[문제 회고]

문제 자체가 깊게 사고할 부분도 없으며 완전 탐색이 필요하며 배열의 정렬이 필요하다는 부분은 문제를 이해하자마자 바로 떠올릴 수 있었다. 하지만 배열의 완전 탐색 과정과 배열을 정렬한 후 필요한 값인 최대값만 뽑아내는 과정에서 효율적인 방법을 떠올리는 데에 시간을 좀 할애했다. 탐색 횟수를 줄이려고 노력했고 정렬을 가능한 적은 횟수로 처리하려고 시도해보았다.

 

[문제 링크]

 

https://leetcode.com/problems/count-pairs-whose-sum-is-less-than-target/

 

[문제 사고]

순서쌍을 구성하고 순서쌍 내부의 값의 범위가 주어지며 순회를 해여하기 때문에 이중 반복문을 사용해야겠다고 생각했다. 이중 반복문에 마지막 조건처리를 해주며 조건이 참일 경우 임의로 선언한 변수에 1씩 증가시키며 값을 도출해 내야겠다고 생각했다.

 

[풀이과정]

1. i와 j 값의 범위가 주어졌기 때문에 순서쌍을 이루며 값 순회를 하기 위해 이중 반복문을 작성한다.
2. 순서쌍의 모습을 ( i , j )로 갖고 가며 j의 값이 i의 값보다 커야하기 때문에 이중 반복문 중에 i 값에 대한 반복문을 j값에 대한 반복문 내부에 작성하여 이중 반복문을 작성한다.
3. 순서쌍의 값과 같은 index 값을 배열에서 가져오며 target 값과 비교하여 주어진 조건에 충족하다면 answer로 선언해둔 0 값에 1씩 더하는 코드를 작성해준다.

 

[제출한 코드]

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var countPairs = function(nums, target) {
    let answer = 0;
    for(let j = 1; j < nums.length; j++){
        for(let i = 0; i < j; i++){
            if(nums[i]+nums[j] < target){
                answer += 1;
            }
        }
    }
    return answer;
};

 

[회고]

오늘 문제 또한 어렵지 않았다. 하지만 신중히 생각해야할 부분이 있었다. 문제를 보자마자 순서쌍을 보고 이중 반복문을 도는 코드가 필요하겠구나 싶었다. 하지만 i의 값이 j보다 작아야했기 때문에 순서쌍의 첫번째 요소에 들어가는 값에 대한 반복문을 중첩 반복문으로 넣었다. i,j의 순서는 상관이 없지만 일반적으로 많이 읽는 순서로 i를 순서쌍의 1번째 요소로 생각을 하고 코드를 작성해보았다. 코드 구현 자체는 어렵지 않았지만 조금더 효율적이고 빠른 런타임을 가져갈 수 있는 방법이 있는지 생각을 해 볼 필요가 있다고 생각한다.

 

[문제 링크]

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

[문제 사고]

오늘의 문제도 매우 쉬웠다.

배열 내의 가장 큰 두 수를 뽑아내어 1씩 뺀 다음 곱하는 매우 간단한 문제였다.

 

[풀이과정]

 

1. 조건이 담긴 이중 배열을 순회하며 각 요소마다 그 안의 요소를 출력하여 주어진 배열을 조작하는 형태를 구상한다.
2. 조건에 맞게 주어진 배열을 slice method를 이용해 자르는 코드를 작성한다.
3. 이어서 잘린 배열을 오름차순으로 정렬하기 위해 sort method를 이용한다.
4. 정렬된 배열을 순회하며 조건에 맞는 index의 요소가 담긴 배열을 반환한다.

 

[제출한 코드]

function solution(array, commands) {
    const arr = commands.map(e => (array.slice(e[0]-1,e[1]).sort((a,b) => a - b))[e[2]-1] )
    return arr
}

 

[회고]

문제 자체는 어렵지 않았다. 하지만 이중 배열을 순회하며 그 안에서 주어진 배열에 맞게 배열 method를 사용하는 과정에서 index를 생각하는 부분에서 어려움을 느꼈다. 배열 자체의 index 값을 이용하는게 아니라 배열 내 요소의 위치를 갖고 코드를 작성하는 과정이 필요해서 index에 접근하기 위해서는 주어진 조건에서 1을 뺀 다음 코드를 작성해야 했다. 문제 해결 방법을 떠올리는데에는 어려움이 없었지만 구현 능력이 조금 부족했던 문제였다.

[문제 링크]

https://leetcode.com/problems/maximum-product-of-two-elements-in-an-array/description/

 

[문제 사고]

오늘의 문제는 매우 쉬웠다.

배열 내의 가장 큰 두 수를 뽑아내어 1씩 뺀 다음 곱하는 매우 간단한 문제였다.

 

[풀이과정]

1. 배열을 내림차순으로 정렬하는 과정에서 sort method를 사용했다.
2. 내림차순 배열 내에서 첫번째, 두번째 인덱스의 요소를 뽑아낸다.
3. 각 요소 값에서 1씩 빼서 곱하는 연산 작업을 처리한 후 반환한다.

 

[회고]

처음에는 정답을 담는 변수 answer을 선언한 후 그 변수를 return하는 코드를 작성하였는데 런타임과 메모리 효율을 고려하여 정답에 해당하는 값을 바로 return 하는 방식으로 변경하였다.

 

[제출한 코드]

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxProduct = function(nums) {
    const arr = nums.sort((a,b) => b-a);
    return (arr[0]-1) * (arr[1]-1);
};

문제 링크 : https://leetcode.com/problems/minimum-number-game/

 

오늘의 문제는 보자마자 스택과 큐를 떠올렸지만 애매한 느낌을 받았었다.

자료구조에 대해서 잘 모르다보니 문제의 토픽을 확인해보니 힙 자료구조를 사용해야 한다고 알려주었다.

하지만 힙 자료구조에 대해서 모르기 때문에 알고 있는 개념을 이용해서 구현해 보았다.

 

1. 가장 작은 요소를 순서대로 제거하여 새로운 배열에 넣는 작업이 필요하므로 정렬하는 코드를 처음에 작성하였다.

2. 정렬한 배열의 가장 앞(최소 요소)에서부터 2개씩 끊어서 제거한 후 새로운 배열에 push하는 작업을 거쳤다.

 

문제를 풀고 돌이켜보니 반복문 내에서 slice와 sort method를 사용할 필요 없이 arr 배열에 i,i+1의 인덱스로 뒤집어서 넣으면 되는 간단한 방법이 있다는 것을 깨달았다.

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var numberGame = function(nums) {
    const arr = [];
    const newNums = nums.sort((a,b) => a - b);
    for(let i = 0; i < nums.length; i += 2){
        arr.push(newNums.slice(i,i+2).sort((a,b) => b-a))
    }
    return arr.flat()
};

 

오늘은 문제 풀이를 성공하지 못했다.

문제의 구성을 보고 스택 자료구조 형태를 떠올리고 나름대로 구현을 했지만 디테일한 valid 조건 검사를 하지 못한 것 같다.

문제에서 사용되는 괄호들을 한 쌍으로 묶어 객체 형태로 저장하고, 스택을 구현할 빈 배열 하나를 생성하였다.

주어진 문자열을 for...of문을 사용하여 순회하며 FILO에 맞게 스택에 쌓고 빼며 객체의 key: value 쌍을 이용하여 비교하는 작업을 수행하였다.

테스트 케이스를 추가하고 경우의 수를 더 생각하여 코드를 수정해 정답을 맞출 계획이다.

/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
    const obj = {'(':')','{':'}','[':']'};
    const answer = [];
    if(s.length % 2 === 1){ return false}
    else{
        for(const value of s){
            if(obj[value]){ answer.push(value)}
            else if(answer.length === 0 && obj[value] == false){return false}
            else if(obj[answer.pop()] === value){return true}
            else if(obj[answer.pop()] !== value){return false}
        }
    }
    if(answer.length !== 0){return false}
};

오늘의 문제는 스택/큐에 관한 문제였다.

스택과 큐는 자료구조를 공부할 때 가장 처음 접한 개념이였기 때문에 알고 있었다.

스택은 FILO, 큐는 FIFO의 형태를 지닌다.

 

본 문제에서는 스택 자료구조를 구현하며 스택의 특징을 이용하여 문제를 풀었다.

새로운 배열에 기존 배열의 요소들이 하나씩 쌓여져 가는 과정에서 스택 자료구조를 생각할 수 있었다.

처음에 주어진 배열의 요소들을 순회하며 한 개씩 새로운 배열에 넣는 작업부터 시작하였다.

다음 작업으로는 순차적으로 요소를 넣는 과정에서 가장 마지막으로 들어간 요소와 새로 삽입할 요소가 같은 값일 경우에는 새로 삽입한 요소가 새로운 배열의 마지막에 삽입되었다가 가장 먼저 나오는 형태를 띄기 때문에 FIFO를 충족하게 된다.

위와 같은 과정을 반복하다 보면 중복되는 값은 사라지고 정답에 해당하는 요소들만 남게 된다.

function solution(arr)
{
    const answer = [];
    arr.map(e => {
        if(answer[answer.length-1] !== e){
            answer.push(e)
        }
    })
    return answer;
}

처음에는 무작정 주어진 두 배열을 순회하면서 요소를 하나씩 비교한 후 일치하지 않는 요소 값을 반환하는 코드를 작성하였다.

하지만 당연히 효율적이지 못했고 풀어내기에 어려움이 있었다.

해시라는 자료구조를 처음으로 공부해보고 Map을 사용하여 주어진 배열들을 순회하며 조건을 충족하지 못하는 요소만 반환하도록 코드를 작성하여 풀어보았다.

function solution(participant, completion) {
    const PHash = new Map();
    const arr = participant.forEach(e => {
        if(PHash.has(e)){
            PHash.set(e,PHash.get(e) + 1)
        }else{
            PHash.set(e,1)   
        }
    });
    const answerArr = completion.map(e => {
        PHash.set(e, PHash.get(e) - 1)
        if(PHash.get(e) === 0){
            PHash.delete(e)
        }
    })
    return [...PHash][0][0]
}

+ Recent posts