너무너무 멋져 눈이눈이 부셔
[JS] 백준 1874 스택 수열 node.js 자바스크립트 풀이 본문
문제
스택 (stack)은 기본적인 자료구조 중 하나로, 컴퓨터 프로그램을 작성할 때 자주 이용되는 개념이다. 스택은 자료를 넣는 (push) 입구와 자료를 뽑는 (pop) 입구가 같아 제일 나중에 들어간 자료가 제일 먼저 나오는 (LIFO, Last in First out) 특성을 가지고 있다.
1부터 n까지의 수를 스택에 넣었다가 뽑아 늘어놓음으로써, 하나의 수열을 만들 수 있다. 이때, 스택에 push하는 순서는 반드시 오름차순을 지키도록 한다고 하자. 임의의 수열이 주어졌을 때 스택을 이용해 그 수열을 만들 수 있는지 없는지, 있다면 어떤 순서로 push와 pop 연산을 수행해야 하는지를 알아낼 수 있다. 이를 계산하는 프로그램을 작성하라.
입력
첫 줄에 n (1 ≤ n ≤ 100,000)이 주어진다. 둘째 줄부터 n개의 줄에는 수열을 이루는 1이상 n이하의 정수가 하나씩 순서대로 주어진다. 물론 같은 정수가 두 번 나오는 일은 없다.
출력
입력된 수열을 만들기 위해 필요한 연산을 한 줄에 한 개씩 출력한다. push연산은 +로, pop 연산은 -로 표현하도록 한다. 불가능한 경우 NO를 출력한다.
풀이
1부터 ~ N까지의 수를 줬을 때 이 수를 가지고 push, pop을 하여 입력값처럼 만들어야 한다. 만약 안되면 NO를 출력한다.
8
4
3
6
8
7
5
2
1
이 입력이 주어진다면 [1,2,3,4,5,6,7,8]의 수열을 push pop해서 [4,3,6,8,7,5,2,1]로 만들어야 한다는 소리이다.
그리고 항상 오름차순으로 push 해야 한다(문제 조건)
그렇다면 우리는 저걸 만들기위해
[1,2,3,4] 순서로 push -> + + + + 출력
4 pop => - 출력, 현재 스택은 [1,2,3]
3 pop => - 출력, 현재 스택 [1.2]
5,6 push => + + 출력, 현재 스택 [1,2,5,6]
6 pop => - 출력, 현재 스택 [1,2,5]
8까지 push => + + 출력, 현재 스택 [1,2,5,7,8]
나머지 순서대로 모조리 pop -> - - - - - 출력
이렇게 하면 [4,3,6,8,7,5,2,1]를 만들 수 있다.
참고
1. 일단 1~N까지의 수를 오름차순으로 스택에 넣어주기 위해서 새로운 배열 queue를 만들었다. queue구조라기 보다 일단 앞에서 부터 순서대로 선출되기만 하는 배열이라서 이름을 queue로 했다. 그런데 지금 생각하니 굳이 새 배열 안만들고 변수 1로 초기화 한다음 1씩 반복문 돌면서 늘렸어도 될 거 같다.
2. stack과 ans를 빈 배열과 빈 문자열로 초기화. ans는 계속 console.log로 하면 시간효율에 안좋을 거 같아서 문자열에 추가만했다가 마지막에 한꺼번에 출력할 생각.
3. 이중 반복문을 썼다. for문은 N만큼 돈다. while 문은 절대로 N만큼 돌지 않을 것같아서 시간초과가 나지 않는다 판단하고 썼다.
풀이 과정
1. for문을 N번 돌면서, 지금 들어오는 목표값을 targetNum에 할당한다.
2. 목표가 4라면 1,2,3,4까지 넣어줘야 한다. 항상 오름차순으로 들어오므로 queue의 첫번째 값이 targetNum보다 작거나 같을때까지 stack에 넣는다. ans도 + 로 추가한다.
3. 만약 스택 마지막 값이 내 목표값이면 스택을 pop한다. ans에도 -를 추가한다.
이때 만약 스택 마지막 값이 목표값이 아니라면 ans 를 No로 갱신한다. 스택은 항상 마지막 값만 비교하면 된다.
어려웠던 점
1. 문제가 뭔소린지 몰랐다.
입력값으로 1~N까지의 수열을 만들라고...? 아니면 입력값을 만들라고?
잘 모르겠으면 일단 입출력부터 보자
// 스택에 push 하는 수는 반드시 오름차순.
const filePath = process.platform === 'linux' ?
'/dev/stdin' : './input.txt';
let input = require('fs').readFileSync(filePath).toString().trim().split('\n');
let numCnt = Number(input[0])
let queue = []
let stack = []
let ans = ""
for (let i=1; i<=numCnt; i++){
queue.push(i)
}
for (let i=1; i <= numCnt;i++){
let targetNum = Number(input[i])
while(queue[0]<=targetNum){
stack.push(queue.shift())
ans += '+\n'
}
if(stack[stack.length-1] === targetNum){
stack.pop()
ans += '-\n'
}else{
ans = 'NO'
break
}
}
console.log(ans)
'멋있는 JavaScript' 카테고리의 다른 글
[JS] 자바스크립트 문법 - 기초 문법과 변수 feat deep dive (1) | 2024.03.28 |
---|---|
[JS] 백준 16967 배열 복원하기 자바스크립트 node.js 풀이 (0) | 2024.03.28 |
자바스크립트 동작 원리 (1) | 2024.03.15 |
[JS] 백준 2467 용액 자바스크립트 node.js 풀이 (2) | 2024.03.14 |
[JS] 자바스크립트의 등장 배경에 대해서 이해하기 (0) | 2024.03.13 |