문제








풀이
재영
/* 1. 기억을 해야 됨(병합한 것들) 2. 해제를 해야 됨. Union-find */ const EMPTY_CELL_VALUE = 'EMPTY'; class Printer { constructor() { this.result = []; } push(value) { this.result.push(value) } print() { return this.result; } } class Table { constructor() { this._key = 1; // 업데이트할 키를 지정 +1 this._cacheMap = new Map(); // 병합 시 '기억'을 해야 됨. 값을 기억. this._table = Array.from({ length: 51 }, () => new Array(51).fill(null)); // 기억을 하는 곳 (2차원 배열 - 키) 타는 것 없이 바로 공통의 키로 // 병합된 애들끼리는 같은 키를 공유하면, 병합의 의미 가능 this.printer = new Printer(); } get COMMAND_UPDATE() { return "UPDATE"; } get COMMAND_MERGE() { return "MERGE"; } get COMMAND_UNMERGE() { return "UNMERGE"; } get COMMAND_PRINT() { return "PRINT"; } get rowLength() { return this._table.length; } get colLength() { return this._table[0].length; } get key() { return this._key; } updateKey() { this._key += 1; return this._key; } update(r, c, value = null) { if (value !== null) { this.singleUpdate(r, c, value); } else { this.multipleUpdate(r, c); } }; singleUpdate(row, col, value) { const key = this._table[row][col] ?? this.updateKey(); // 키를 받아서 this._table[row][col] = key; // 배열에다가 키를 메모이제이션 this._cacheMap.set(key, value); // 키에다가는 값을 저장 }; multipleUpdate(value1, value2) { this._cacheMap.forEach((value, key) => { if (value === value1) { this._cacheMap.set(key, value2) } }) // Map을 다 돌아서 같은 값이면 바꿔야 할 값만 변경하면 됨 }; merge(row1, col1, row2, col2) { // 여기 헬 this.tableKey1 = this._table[row1][col1]; // 각각의 셀 키1 this.tableKey2 = this._table[row2][col2]; // 각각 셀 키 2 if (row1 === row2 && col1 === col2) { return; } if (this.tableKey1 === null && this.tableKey2 === null) { const newKey = this.updateKey(); this._table[row1][col1] = newKey; this._table[row2][col2] = newKey; this._cacheMap.set(newKey, null) return; } // 둘 다 애초부터 빈 값 - 병합만 하는 케이스 if (this.tableKey1 === null) { this._table[row1][col1] = this.tableKey2; return; } if (this.tableKey2 === null) { this._table[row2][col2] = this.tableKey1; return; } const value1 = this._cacheMap.get(this.tableKey1); const value2 = this._cacheMap.get(this.tableKey2); const nextKey = value1 ? this.tableKey1 : value2 ? this.tableKey2 : this.tableKey1; for (let i = 1; i < this.rowLength; i += 1) { for (let j = 1; j < this.colLength; j += 1) { if (this._table[i][j] === this.tableKey2 || this._table[i][j] === this.tableKey1) { this._table[i][j] = nextKey; // 2 -> 1 로 병합 시 바꿔야 할 같은 키들이 있었을 것 } } } this._cacheMap.delete(nextKey === value1 ? value2 : value1); } unMerge(r, c) { const row = +r; const col = +c; const key = this._table[row][col]; if (key === null) return; const value = this._cacheMap.get(key); for (let i = 1; i < this.rowLength; i += 1) { for (let j = 1; j < this.colLength; j += 1) { const nowKey = this._table[i][j]; if (nowKey === key) { this._table[i][j] = null; } } } this._cacheMap.delete(key); const newKey = this.updateKey(); this._cacheMap.set(newKey, value); this._table[row][col] = newKey; } print(row, col) { const key = this._table[row][col]; this.printer.push(this._cacheMap.get(key) ?? EMPTY_CELL_VALUE) } getResult() { return this.printer.print() } } function solution(commands) { const table = new Table(); commands.forEach((value) => { const [command, ...args] = value.split(" "); if (command === table.COMMAND_UPDATE) { table.update(...args); } else if (command === table.COMMAND_MERGE) { table.merge(...args); } else if (command === table.COMMAND_UNMERGE) { table.unMerge(...args); } else if (command === table.COMMAND_PRINT) { table.print(...args); } }) return table.getResult() }