본문 바로가기
패스트캠퍼스/자습

자바스크립트로 하는 자료구조와 알고리즘(5장) - 배열

by sunnykim91 2019. 10. 22.

배열

 

삽입 : push()를 사용 / O(1)시간

삭제 :

  - pop()를 사용 / O(1)시간  , pop은 배열의 맨뒤 요소 제거

  - shift()는 맨 앞에서 제거

접근 : array[i] 로 접근

 

반복문

 

for 

while

 

for in 문 과 for of문의 차이

in앞에 지정된 변수 index는 배열의 인덱스이다.

of앞에 지정된 변수 elemnet는 배열의 항목이다.

 

 

도움 함수들 

 

.slice(begin, end)

배열의 시작 인덱스와 끝 인덱스 두 개의 매개변수를 받아서 그 시작인덱스부터 end인덱스 까지 배열의 일부를 반환

begin인덱스만 있는 경우 -> end인덱스는 배열의 최대값으로 가정

인덱스를 안주면 -> 복사본을 만든다. 하지만, 다음예제를 보면?

var array1 = [1,2,3,4]
console.log(array1.slice() === array1);  // false

** 배열의 내용이 동일하지만, 다른 주소 값을 가지므로 false이다.

 

.splice(begin, size, element1, element2...)  ** 원본 배열이 바뀜!

기존 항목을 제거하거나 신규 항목을 추가함으로써 배열의 내용을 반환하고 변경

var array = [1,2,3,4]

array.splice();  // []를 반환
array.splice(1,2); // [2,3]을 반환
array.splice(1,2,5,6,7) // [2,3]을 반환, array=[1,5,6,7,4] 가 됨

.concat()

신규 항목을 배열의 맨 뒤에 추가한 다음, 해당 배열을 반환

var array = [1,2,3,4];

array.concat();  // [1,2,3,4]
array.concat([2,3,4]);  // [1,2,3,4,2,3,4]

 

문제

 

배열 arr이 있고 어떤 수 weight가 주어졌을 때, 합쳐서 weight가 되는 배열 내 항목 두 개의 인덱스를 반환하라.
만약 합쳐서 weight가 되는 항목 두개가 존재하지 않는 경우 -1을 반환하라.

 

보통, 이중 for문을 사용하여 하나씩 비교하여 구현할 수 있지만, 시간 복잡도가 O(n^2)이 된다.

 

아래와 같이 해시테이블을 사용하여, O(n)시간에 구현 할 수 있다.


function findSumBetter(arr, weight) {
  let hashtable = {};

  for(let i=0, arrLength=arr.length; i<arrLength; i++) {
    let currentElement = arr[i];
    let difference = weight - currentElement;

      if(hashtable[currentElement] != undefined) {
        return [i, hashtable[currentElement]];
      } else {
        hashtable[difference] = i;
      }
  }
  return -1;
}

console.log(findSumBetter([1,2,3,4,5], 9));

 

 

k개의 정렬된 배열에서 공통 항목 찾기

let arr1 = [1, 5, 5, 10];
let arr2 = [3, 4, 5, 5, 10];
let arr3 = [5, 5, 10, 20];
let output = [5, 10];

배열의 개수가 3개이므로 k=3

 

function commonElements(kArray) {
  let hashmap = {};
  let last;
  let answer = [];

  for ( let i = 0, kArrayLength = kArray.length; i < kArrayLength; i++ ) {
    let currentArray = kArray[i];
    last = null;
    for ( let j = 0, currentArrayLen = currentArray.length; j < currentArrayLen; j++ ) {
      let currentElement = currentArray[j];
      if(last != currentElement) {
        if(! hashmap[currentElement]){
          hashmap[currentElement] = 1;
        } else {
          hashmap[currentElement]++;
        }
      }
      last = currentElement;
    }
  }

  for ( let prop in hashmap) {
    if(hashmap[prop] === kArray.length) {
      answer.push(parseInt(prop));
    }
  }

  return answer;
}

console.log(commonElements([[1, 2, 3], [1,2,3,4], [1,2]]));

 

자바스크립트 함수형 배열 메소드

 

map : 매개변수로 전달된 함수 변환을 배열의 모든 항목에 적용한 다음 변환이 적용된 항목들을 포함하는 신규 배열을 반환

 

filter : 매개변수로 전달된 조건을 충족시키는 배열들만 반환

 

reduce: 매개변수로 전달된 변환 함수를 사용해 배열의 모든 항목을 하나의 값으로 결합

**두번째 인자로 initalValue를 줄 수 있다.

 

다차원 배열

 

자바스크립트에는 다차원배열이 없다.

-> 가변 배열이 있음!

 

 

나선형으로 배열 출력하기!

 

 왼쪽에서 오른쪽으로 출력

 위에서 아래쪽으로 출력

 오른쪽에서 왼쪽으로 출력

 아래쪽에서 위쪽으로 출력

 위 4가지 출력에 대해 제한을 걸기

 

 상부 행

 하부 행

 왼쪽 열

 오른쪽 열

 이 4가지 변수를 적절히 위 출력함수들에서 써주고 증가 시키면 된다!

var M = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]];

function spiralPrint(M){
  let topRow = 0;
  let leftCol = 0;
  let btmRow = M.length - 1;
  let rightCol = M[0].length - 1;

  while (topRow < btmRow && leftCol < rightCol) {
    for ( let col = 0; col <= rightCol; col++ ){
      console.log(M[topRow][col]);
    }
    topRow++;
    for ( let row = topRow; row <= btmRow; row++ ){
      console.log(M[row][rightCol]);
    }
    rightCol--;
    if(topRow <= btmRow) {
      for (let col = rightCol; col >= 0; col--){
        console.log(M[btmRow][col]);
      }
      btmRow--;
    }
    if(leftCol <= rightCol) {
      for (let row=btmRow; row > topRow; row--){
        console.log(M[row][leftCol]);
      }
      leftCol++;
    }
  }
}

console.log(spiralPrint(M));

 

시간복잡도는 O(mn)이다. m은 열, n은 행 개수

 

 

틱택토에서 승자 맞추기

행을 먼저 확인

열을 확인

그리고 대각선 확인 (왼쪽대각선, 오른쪽 대각선)

이런식으로 하면 된다.

 

길 찾기

var board =
`%e%%%%%%%%%\n
%...%.%...%\n
%.%.%.%.%%%\n
%.%.......%\n
%.%%%%.%%.%\n
%.%.....%.%\n
%%%%%%%%%x%`

현재 위치가 x일때 e(출구)를 찾아라

 

var rows = board.split("\n");

function generateColumnArr(arr) {
    return arr.split("");
}
var mazeMatrix = rows.map(generateColumnArr);

function findChar(char, mazeMatrix) {
  var row = mazeMatrix.length,
        column = mazeMatrix[0].length;

    for (var i = 0; i < row; i++) {
        for (var j = 0; j < column; j++) {
            if (mazeMatrix[i][j] == char) {
                return [i, j];
            }
        }
    }  
}

function printMatrix(matrix) {
    var mazePrintStr = "",
        row = matrix.length,
        column = matrix[0].length;

    for (var i = 0; i < row; i++) {

        for (var j = 0; j < column; j++) {
            mazePrintStr += mazeMatrix[i][j];
        }

        mazePrintStr += "\n";

    }
    console.log(mazePrintStr);
}

function mazePathFinder(mazeMatrix) {
    var row = mazeMatrix.length,
        column = mazeMatrix[0].length,
        startPos = findChar('e', mazeMatrix),
        endPos = findChar('x', mazeMatrix);

    path(startPos[0], startPos[1]);

    function path(x, y) {
        if (x > row - 1 || y > column - 1 || x < 0 || y < 0) {
            return false;
        }
        // Found
        if (x == endPos[0] && y == endPos[1]) {
            return true;
        }
        if (mazeMatrix[x][y] == '%' || mazeMatrix[x][y] == '+') {
            return false;
        }
        // Mark the current spot
        mazeMatrix[x][y] = '+';
        printMatrix(mazeMatrix);

        if (path(x, y - 1) || path(x + 1, y) || path(x, y + 1) || path(x - 1, y)) {
            return true;
        }
        mazeMatrix[x][y] = '.';
        return false;
    }
}

mazePathFinder(mazeMatrix);

 

 

행렬 회전

101

001

111

왼쪽으로90 도 회전해라

111

001

101

 

행렬의 세 번째 열이 회전된 행렬의 첫 번째 행이 된다.

행렬의 두 번째 열이 회전된 행렬의 두 번째 행이 된다.

행렬의 첫 번째 열이 회전된 행렬의 세 번쨰 행이 된다.

 

var matrix = [[1,0,1],[0,0,1],[1,1,1]];

function rotateMatrix90Left (mat) {
  var N = mat.length;

  for(var x = 0; x <N/2; x++) {
    for(var y = x; y<N-x-1; y++){
      var temp = mat[x][y];

      mat[x][y] = mat[y][N-1-x];
      mat[y][N-1-x] = mat[N-1-x][N-1-y];
      mat[N-1-x][N-1-y] = mat[N-1-y][x];
      mat[N-1-y][x] = temp;
    }
  }
}

rotateMatrix90Left(matrix);
console.log(matrix);

 

반응형