Spiral Matrix II

HS K·2023년 5월 10일

문제설명

Given a positive integer n, generate an n x n matrix filled with elements from 1 to n2 in spiral order.

제한사항

  • 1 <= n <= 20

입출력 예

Example 1:

https://assets.leetcode.com/uploads/2020/11/13/spiraln.jpg

Input: n = 3
Output: [[1,2,3],[8,9,4],[7,6,5]]

Example 2:

Input: n = 1
Output: [[1]]

행동영역(알고리즘을 설계하는 사고과정)

  1. 규칙 알고리즘화 하기
  • 결과를 쭉 적어본다면 알고리즘화 할 수 있는 규칙이 보이는지 찾기

n = 2
[[1,2], [4,3]]

n= 3
[[1,2,3],[8,9,4],[7,6,5]]

n=4
[[1,2,3,4][12,13,14,5] [11, 16, 15, 6] , [10, 9, 8, 7]]

하지만 실패했다.

내가 쓴 답

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function(n) {
    const matrix = Array(n).fill().map(() => Array(n).fill(0)); // n x n matrix filled with 0s
    let num = 1, start = 0, end = n - 1;
  
    while (start <= end) {
        for (let j = start; j <= end; j++) {
            matrix[start][j] = num++; // top row
        }

        for (let i = start + 1; i <= end; i++) {
            matrix[i][end] = num++; // right column
        }

        for (let j = end - 1; j >= start; j--) {
            matrix[end][j] = num++; // bottom row
        }

        for (let i = end - 1; i > start; i--) {
            matrix[i][start] = num++; // left column
        }

        start++;
        end--;
    }

    return matrix;
};

다른풀이

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function(n) {
     let matrix = [];
  let nums = [];

  for (let i = 0; i < n; i++) {
    matrix[i] = [];
  }

  for (let i = 1; i <= n * n; i++) {
    nums.push(i);
  }
  nums.reverse();

  let top = 0;
  let left = 0;
  let right = n - 1;
  let bottom = n - 1;

  let addElement = (row, columm) => {
    matrix[row][columm] = nums.pop();
  };

  while (nums.length) {
    for (let i = left; i <= right && nums.length; i++) {
      addElement(top, i);
    }
    top++;

    for (let i = top; i <= bottom && nums.length; i++) {
      addElement(i, right);
    }
    right--;

    for (let i = right; i >= left && nums.length; i--) {
      addElement(bottom, i);
    }
    bottom--;

    for (let i = bottom; i >= top && nums.length; i--) {
      addElement(i, left);
    }
    left++;
  }

  return matrix;
};

속도 백분위

피드백

규칙은 이미 문제에서 파악하기 쉽게 나와있어서 규칙을 파악하는데 시간을 쓰진 않았다. 하지만 그 규칙을 응용할 생각을 해야지, 규칙을 코드로 작성할 능력이 부족하다고 다른 방법으로 만들려고 했기 때문에 겪었던 문제였다.

복습

  1. map()

array.map(function(currentValue, index, arr), thisValue)
map()에 전달되는 콜백 함수는 최대 세 개의 인자(currentValue, index, arr)를 받을 수 있다.
이때 이 인자들을 모두 사용할 수도 있고, 일부만 사용하거나 아예 사용하지 않을 수도 있다. 아무런 인자를 받지 않는다는 것은 그 콜백 함수가 아무런 인자를 사용하지 않는다는 것을 의미한다.
하지만 세 가지 인자 중 어느 것을 실제로 사용할지는 map()에 전달하는 콜백 함수에 달려있다.

  • map()함수에서 콜백함수의 작성
    array.map(function(currentValue, index, arr), thisValue) 에서 function(currentValue, index, arr)는 함수이니까
    array.map(function(currentValue, index, arr) {}, thisValue)로 적어도 될까?
    → 적어도 되긴한다. 하지만 {}는 함수의 본문을 나타내는 구문으로써, 아무런 동작을 하지 않는 함수를 전달하게 되는 것인데, 원래 배열의 각 요소에 대해 아무런 처리도 하지 않고 undefined를 반환하게된다
  • Array(n).fill().map(() => Array(n).fill(0)) 작동과정
    (1) Array(n).fill() : 이 코드는 길이가 n이고 모든 요소가 undefined인 배열을 생성한다.
    (2) map(() => Array(n).fill(0)) : 이 코드는 map 함수를 사용해 위에서 생성한 배열의 각 요소를 새로운 배열로 바꾼다.
    각 새 배열은 길이가 n이고 모든 요소가 0인 배열이고, map 함수의 콜백은 인자를 받지 않고, 각 요소에 대해 동일한 동작을 수행한다.
    cf) undefined는 변수가 선언되었으나 값이 할당되지 않은 상태를 나타낸다. 수학으로 치자면 빈 집합에 가깝다.
profile
주의사항 : 최대한 정확하게 작성하려고 하지만, 틀릴내용이 있을 수도 있으니 유의!

0개의 댓글