2021_07_18 문제 풀이
문제 URL : https://programmers.co.kr/learn/courses/30/lessons/64061
코딩테스트 연습 - 크레인 인형뽑기 게임
[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4
programmers.co.kr
문제
board 판에서 moves의 원소들의 위치에 있는 제일 위에 있는 인형을 stack 형태로 담아서 저장하고, 2개 이상 중복되어 제거되는 인형들의 갯수를 리턴하는 문제였다.
의사코드
1. 삽질
// [[0,0,0,0,0], > board[j] === row
// [0,0,1,0,3],
// [0,2,5,0,1], j가 적을 수록 높은 부분
// [4,2,4,4,2],
// [3,5,1,3,1]]
// 인형을 담을 stack 빈배열 선언 / stack
// result = 0;
//moves를 순회한다 >
// 변경된 배열을 저장할 빈배열 선언 temp
// boardIndex 저장 변수 선언
// board를 순회한다
// board[j][moves[i - 1]]의 값이 0이 아니라면 (값이 있는 것)
// boardIndex = j
// board[j][moves[i - 1]] 값을 stack 에 추가해야 함
// stack의 마지막 요소가 board[j][moves[i] - 1] 와 같다면
// result += 2; (이전 + 현재 값)
// stack.pop으로 마지막 요소 제거
// 그렇지 않다면
// stack에 board[j][moves[i] - 1] 를 추가한다
// 나머지 인덱스들을 이어 붙여야 함 /
// temp = board[j].slice(0, moves[i] - 1).concat([0, ...board[j].slice(moves[i] - 1) / 깊은복사 가공
// 반복문 종료 break
// board = board.slice(0, j).concat([...temp, board.slice(j)]) / 다시 재가공해서 할당한다
// result를 리턴한다
처음에 작성했던 의사 코드였다. 이중 배열을 가지고 있기때문에 얕은복사를 방지하기 위해 array 프로토타입 메소드 slice, concat으로 핸들링을 해야 한다고 생각했다.
temp 변수에 뺀 인형의 위치에 0을 넣고 이어 붙이고.. 저장해놓은 다음 board 매개변수에 또 이어붙여서 재할당하는 방식이었는데 말도안되는 코드였다.
디버깅 도중 자바스크립트의 깊은 복사, 얕은 복사에 대해 알고있던 개념에 오류가 있다는 것을 발견했고,
https://www.digitalocean.com/community/tutorials/copying-objects-in-javascript
Copying Objects in JavaScript | DigitalOcean
Copying Objects in JavaScript
www.digitalocean.com
개념을 다시 한 번 확인하는 시간을 가졌다.
2. 최종
// [[0,0,0,0,0], > board[j] === row
// [0,0,1,0,3],
// [0,2,5,0,1], j가 작을 수록 높은 부분
// [4,2,4,4,2],
// [3,5,1,3,1]]
// 인형을 담을 stack 빈배열 선언 / stack
// result = 0;
//moves를 순회한다 > let i
// board를 순회한다 let j
// board[j][moves[i] - 1] 값은 빼내야 하는 보드판 열
// 해당 열의 값이 0이 아니라면, 가장 높은 곳에 위치한 인형으로 작업 수행
// 스택에 마지막으로 담겨져 있는 값과 열의 값이 일치하는 지 확인
// 일치한다면, 가장 마지막에 담은 인형과 현재 인형이 2개로 중복되는 것
// 고로 stack의 마지막 요소를 (이전에 담은 인형) 제거
// result에 2를 더한다 (이전 인형 + 현재 인형의 갯수가 2)
// 그게 아니라면 stack에 현재 인형의 값을 추가한다
// board[j][moves[i] - 1] = 0; > 인형을 제거한 위치에 0을 할당
// 반복문을 빠져 나온다
// result를 리턴한다
board 매개변수에 0을 할당하여 메모리에 저장되어있는 값을 변경, board의 원문 배열의 값이 변화할 수 있도록 진행했고, 뽑은 인형들을 저장하는 로직은 1차와 동일하게 stack 자료구조를 사용, 중복되는 인형이라면 array.pop()메소드로 값을 제거하고, 중복되지 않은 인형이라면 push 메소드로 인형을 넣어줄 수 있도록 구현했다.
풀이
function solution(board, moves) {
let stack = [];
let result = 0;
for (let i = 0; i < moves.length; i++) {
for (let j = 0; j < board.length; j++) {
let target = board[j][moves[i] - 1];
if (target !== 0) {
if (stack[stack.length - 1] === target) {
stack.pop();
result += 2;
} else {
stack.push(target);
}
board[j][moves[i] - 1] = 0;
break;
}
}
}
return result;
}
시간복잡도 O(n^2) 의 코드를 구현했다.
이차원 배열을 1차원 배열로 수정하고 O(n)의 코드로 만들 수 있지 않나라는 생각을 했다가 row, col 형태의 보드판이기때문에 다른 아이디어가 떠오르지 않아 이중 반복문을 사용했다.
부족했던 깊은 복사 / 얕은 복사에 대해 다시금 정리할 수 있는 시간을 가질 수 있어 참 다행이었다.
'Algorithm > Algorithm Study' 카테고리의 다른 글
[프로그래머스] 2020 카카오 인턴십 _ 수식 최대화 (도른자) (0) | 2021.08.08 |
---|---|
[프로그래머스] lv3 2019 카카오 블라인드_ 추석 트래픽 (0) | 2021.07.18 |
[프로그래머스] 2020 KAKAO 블라인드 _ 문자열 압축 (0) | 2021.07.11 |
[프로그래머스] 2019 KAKAO 블라인드 _ 오픈 채팅방 (0) | 2021.07.11 |
[프로그래머스] 2021 KAKAO 블라인드 _ 메뉴 리뉴얼 (0) | 2021.07.04 |