Skip to content

Comments

[oh-chaeyeon] 25.01.02#7

Merged
JooKangsan merged 10 commits intomainfrom
ohchaeyeon
Jan 9, 2025
Merged

[oh-chaeyeon] 25.01.02#7
JooKangsan merged 10 commits intomainfrom
ohchaeyeon

Conversation

@oh-chaeyeon
Copy link
Collaborator

[배열]

배열문제를 풀때, 가장 많이 사용되는 메서드랑 알고리즘들을 노션으로 정리해보았습니다!

📌 푼 문제


📝 간단한 풀이 과정

[기초]

배열 자르기

  • 배열의 일부를 잘라내 새로운 배열을 반환하는 메서드인 slice를 사용했음.
function solution(numbers, num1, num2) {
    var answer = numbers.slice(num1, num2 + 1);
    return answer;
}

배열 원소의 길이

  • 배열의 각 요소를 특정 로직에 따라 변환하여 새로운 배열을 반환하는 메서드인 map를 사용함. 여기서는 각 문자열 str의 길이를 반환하는 함수를 사용함.
function solution(strlist) {
    return strlist.map(str => str.length);
}

배열 회전시키기

  • "right"일 경우에, 배열의 마지막 원소만 처음으로 옮기면 되는 걸 이용. (solution([1,2,3], "right") -> [3,1,2])
  • "left"일 경우에, 배열의 첫번째를 마지막으로만 옮기면 되는 걸 이용.
    ( solution([4, 455, 6, 4, -1, 45, 6], "left") -> [455, 6, 4, -1, 45, 6, 4] )
function solution(numbers, direction) {
    if (direction === "right") {
        return [numbers[numbers.length - 1], ...numbers.slice(0, numbers.length - 1)];
    } else if (direction === "left") {
        return [...numbers.slice(1), numbers[0]];
    }
}

중복된 숫자 개수

  • reduce메서드 사용해서 배열을 순회하면서 특정 숫자 n이 몇 번 나오는지를 세도록 구성.
function solution(array, n) {
    var answer = array.reduce((count, num) => {
        return num === n ? count + 1 : count;
    }, 0);
    return answer;
}

[중급]

제일 작은 수 제거하기

  • Math.min(...arr); 사용해서 최솟값을 찾고, filter메서드 사용해서 가장 작은 수를 제외한 배열을 생성해서 반환.
function solution(arr) {
    const min = Math.min(...arr);
    var answer = arr.filter(num => num !== min);;
    return answer.length === 0 ? [-1] : answer;
}

행렬의 덧셈

  • map메서드 사용해서, 두 개의 행렬을 입력받아 같은 위치에 있는 원소들을 더한 새로운 행렬을 만들도록 구성.
function solution(arr1, arr2) {
    var answer = arr1.map((row, i) => {
        return row.map((num, j) =>{
            return num + arr2[i][j];
        })
    })
    return answer;
}

나누어 떨어지는 숫자 배열

  • filter메서드 사용해서, divisor로 나누어 떨어지는 숫자들 필터링
  • 나누어 떨어지는 원소가 없으면 [-1] 반환하도록
  • sort메서드 사용해서, 오름차순으로 정렬되도록
function solution(arr, divisor) {
    var answer = arr.filter(num => num%divisor === 0);
    if(answer.length === 0) return [-1];
    return answer.sort((a, b) => a - b);
}

[심화]

행렬의 곱셈

  • 이 문제에는... 문제 이해부터 막혀서..입출력 예시가 곱셉이 약간 이상하다 생각했는데...찾아보니 행렬의 곱셉이라는 규칙을 알게된,,,,

행렬의 곱셉 규칙

  1. 행렬 ( A )의 열의 수가 행렬 ( B )의 행의 수와 같아야 곱셈이 가능합니다.
  2. 결과 행렬의 크기는 ( A )의 행의 수와 ( B )의 열의 수로 결정됩니다.
    -> 만약 arr1이 3행렬이고, arr2가 2행렬이라면, 결과는 3행렬이 된다는 이야기...

행렬 곱셉하는 방법

arr1 = [[1, 4], [3, 2], [4, 1]] (3행2열)
arr2 = [[3, 3], [3, 3]] 일때, (2행2열)
result은 3행2열이 될 예정.

result[0][0] = arr1[0][0]*arr2[0][0] + arr1[0][1]*arr2[1][0] = 3 + 12 = 15
result[0][1] = arr1[0][0]*arr2[0][1] + arr1[0][1]*arr2[1][1] = 3 + 12 = 15

result[1][0] = arr1[1][0]*arr2[0][0] + arr1[1][1]*arr2[1][0] = 9 + 6 = 15
result[1][1] = arr1[1][0]*arr2[0][1] + arr1[1][1]*arr2[1][1] = 9 + 6 = 15

result[2][0] = arr1[2][0]*arr2[0][0] + arr1[2][1]*arr2[1][0] = 12 + 3 = 15
result[2][1] = arr1[2][0]*arr2[0][1] + arr1[2][1]*arr2[1][1] = 12 + 3 = 15

결과적으로 result = [[15, 15], [15, 15], [15, 15]] 가 된다,
이게 왜 이렇게 이해하기 어려웠는지,,,

function solution(arr1, arr2) {
    const rowsA = arr1.length;  // arr1의 행 수
    const colsA = arr1[0].length; // arr1의 열 수 = arr2의 행 수와 같음
    const colsB = arr2[0].length; // arr2의 열 수

    const result = Array.from({ length: rowsA }, () => Array(colsB).fill(0));

     // 행렬 곱셈
    for (let i = 0; i < rowsA; i++) {
        for (let j = 0; j < colsB; j++) {
            for (let k = 0; k < colsA; k++) {
                result[i][j] += arr1[i][k] * arr2[k][j];
            }
        }
    }
    return result; 
}

교점에 별 만들기

  • 차근차근 푸는 문제... 교점 구하고, 최소 격자판 크기 계사낳고, 결자판에 별찍고
function solution(line) {
    const points = [];

   // 직선의 교점을 찾는 부분
    for (let i = 0; i < line.length; i++) {
        for (let j = i + 1; j < line.length; j++) {
            const [A1, B1, C1] = line[i];
            const [A2, B2, C2] = line[j];

            // 두 직선의 교점 계산
            const denominator = A1 * B2 - A2 * B1;

            if (denominator !== 0) {   // 평행하지 않을 경우
                const x = (B1 * C2 - B2 * C1) / denominator;
                const y = (A2 * C1 - A1 * C2) / denominator;
 
                // 정수 좌표만 추가하도록
                if (Number.isInteger(x) && Number.isInteger(y)) {
                    points.push([x, y]);
                }
            }
        }
    }

   // 정수 좌표의 최소 및 최대 x, y 값을 찾아 최소 사각형의 크기를 결정.
    const xs = points.map(point => point[0]);
    const ys = points.map(point => point[1]);

    const minX = Math.min(...xs);
    const maxX = Math.max(...xs);
    const minY = Math.min(...ys);
    const maxY = Math.max(...ys);

    // 사각형 크기 계산 및 초기화
    const width = maxX - minX + 1;
    const height = maxY - minY + 1;
    const grid = Array.from({ length: height }, () => Array(width).fill('.'));

   // 별 찍기
    for (const [x, y] of points) {
        grid[maxY - y][x - minX] = '*';
    }

    return grid.map(row => row.join(''));
}

n^2 배열 자르기

  • 이 문제는 규칙찾는게 힘든 문제였다...는... 규칙은 우리의 GPT이용해서 찾음.
  • 2차원 배열을 모두 생성해서 구하는게 아닌, 필요한 값만 계산하도록

n=3, left=2, right=5일때, 2차원 배열이

1 2 3
2 2 3
3 3 3
이기에, 1차원 배열로 배치하면, [1, 2, 3, 2, 2, 3, 3, 3, 3]으로 결과값은 [3, 2, 2, 3]이 된다.

규칙을 찾는다면,

  1. 행(i)과 열(j) 변환: i = Math.floor(k / n) , j = k % n
    이를 통해 1차원 인덱스 k를 2차원 좌표 (i, j)로 변환.

  2. 값 계산 규칙 : 값 = Math.max(i, j) + 1
    행 번호와 열 번호 중 더 큰 값에 1을 더한 것이 배열의 값.

1차원 배열에서 k = 2부터 k = 5까지 규칙대로 계산한다면,

k = 2
i = Math.floor(2 / 3) = 0
j = 2 % 3 = 2
Math.max(i, j) + 1 = Math.max(0, 2) + 1 = 3
결과: 3

k = 3
i = Math.floor(3 / 3) = 1
j = 3 % 3 = 0
Math.max(i, j) + 1 = Math.max(1, 0) + 1 = 2
결과: 2

k = 4
i = Math.floor(4 / 3) = 1
j = 4 % 3 = 1
Math.max(i, j) + 1 = Math.max(1, 1) + 1 = 2
결과: 2

k = 5
i = Math.floor(5 / 3) = 1
j = 5 % 3 = 2
Math.max(i, j) + 1 = Math.max(1, 2) + 1 = 3
결과: 3

최종 배열은 [3, 2, 2, 3]이 된다,,

function solution(n, left, right) {
    const answer = [];
    for (let k = left; k <= right; k++) {
        const i = Math.floor(k / n); // 행 :  k가 몇 번째 행에 속하는지
        const j = k % n;  // 열 : k가 몇 번째 열에 속하는지
        answer.push(Math.max(i, j) + 1);
    }
    return answer;
}

후기

사실 기초, 중급 문제는 8시 전에 풀어놓고 8시에 심화문제 풀기 시작했는데, 심화에서 확 어려워져서 헤맸네요....
그리고 커밋을 영어로 하는걸 보긴 했는데, 문제가 한글이여서 한글로 적었는데 다음부터는 영어로 적어둘게요!

@oh-chaeyeon oh-chaeyeon self-assigned this Jan 2, 2025
Copy link
Collaborator

@Moonjonghoo Moonjonghoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전반적으로 메서드를 활용해 코드가짜여져있어 깔끔했고,가독성이 좋아서 리뷰하기편했습니다!
한주 고생하셨어요

@JooKangsan JooKangsan merged commit 4ad8b58 into main Jan 9, 2025
3 checks passed
@bona1122
Copy link
Collaborator

bona1122 commented Jan 9, 2025

저는 Math.floor랑 원본 값 을 비교해서 정수를 판별했는데, Number.isInteger라는 정수판별 메서드가 있군요...!
코드 전체적으로 잘 보고 배워갑니다. 감사합니다!

bona1122 pushed a commit to bona1122/AlgorithmStudy that referenced this pull request Jan 9, 2025
* 배열 자르기 / 기초

* 배열 원소의 길이 / 기초

* 배열 회전시키기 / 기초

* 중복된 숫자 개수 / 기초

* 제일 작은 수 제거하기 / 중급

* 행렬의 덧셈 / 중급

* 나누어 떨어지는 숫자 배열 / 중급

* 행렬의 곱셈 / 심화

* 교점에 별 만들기 / 심화

* n^2 배열 자르기 / 심화
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants