ํด๋น ๊ฒ์๊ธ์ dev-note-97๋์ [ํ๋ก๊ทธ๋๋จธ์ค] ํ ํธ์ง / Javascript๋ฅผ ์ฐธ๊ณ ํ์ฌ ์์ฑ๋์์์ ๋ฏธ๋ฆฌ ๋ฐํ๋๋ค.

๋ฌธ์  ์ค๋ช
์ ๋ฌด์ฉ ์ํํธ์จ์ด๋ฅผ ๊ฐ๋ฐํ๋ ๋๋์ฆ์์ค์ ์ธํด์ธ ์๋ชฌ๋๋ ๋ช ๋ น์ด ๊ธฐ๋ฐ์ผ๋ก ํ์ ํ์ ์ ํ, ์ญ์ , ๋ณต๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ ๊ณผ์ ๋ฅผ ๋งก์์ต๋๋ค. ์ธ๋ถ ์๊ตฌ ์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค

์ ๊ทธ๋ฆผ์์ ํ๋์์ผ๋ก ์น ํด์ง ์นธ์ ํ์ฌ ์ ํ๋ ํ์ ๋ํ๋ ๋๋ค. ๋จ, ํ ๋ฒ์ ํ ํ๋ง ์ ํํ ์ ์์ผ๋ฉฐ, ํ์ ๋ฒ์(0ํ ~ ๋ง์ง๋ง ํ)๋ฅผ ๋ฒ์ด๋ ์ ์์ต๋๋ค. ์ด๋, ๋ค์๊ณผ ๊ฐ์ ๋ช ๋ น์ด๋ฅผ ์ด์ฉํ์ฌ ํ๋ฅผ ํธ์งํฉ๋๋ค.
"U X": ํ์ฌ ์ ํ๋ ํ์์ X์นธ ์์ ์๋ ํ์ ์ ํํฉ๋๋ค."D X": ํ์ฌ ์ ํ๋ ํ์์ X์นธ ์๋์ ์๋ ํ์ ์ ํํฉ๋๋ค."C" : ํ์ฌ ์ ํ๋ ํ์ ์ญ์ ํ ํ, ๋ฐ๋ก ์๋ ํ์ ์ ํํฉ๋๋ค. ๋จ, ์ญ์ ๋ ํ์ด ๊ฐ์ฅ ๋ง์ง๋ง ํ์ธ ๊ฒฝ์ฐ ๋ฐ๋ก ์ ํ์ ์ ํํฉ๋๋ค."Z" : ๊ฐ์ฅ ์ต๊ทผ์ ์ญ์ ๋ ํ์ ์๋๋๋ก ๋ณต๊ตฌํฉ๋๋ค. ๋จ, ํ์ฌ ์ ํ๋ ํ์ ๋ฐ๋์ง ์์ต๋๋ค.์๋ฅผ ๋ค์ด ์ ํ์์ "D 2"๋ฅผ ์ํํ  ๊ฒฝ์ฐ ์๋ ๊ทธ๋ฆผ์ ์ผ์ชฝ์ฒ๋ผ 4ํ์ด ์ ํ๋๋ฉฐ, "C"๋ฅผ ์ํํ๋ฉด ์ ํ๋ ํ์ ์ญ์ ํ๊ณ , ๋ฐ๋ก ์๋ ํ์ด์๋ "๋ค์ค"๊ฐ ์ ํ ํ์ ์ ํํฉ๋๋ค(4ํ์ด ์ญ์ ๋๋ฉด์ ์๋ ์๋ ํ๋ค์ด ํ๋์ฉ ๋ฐ๋ ค ์ฌ๋ผ์ค๊ณ , ์์ ๋ ํ์์ ๋ค์ 4ํ์ ์ ํํ๋ ๊ฒ๊ณผ ๋์ผํฉ๋๋ค).

๋ค์์ผ๋ก "U 3"์ ์ํํ ๋ค์ "C"๋ฅผ ์ํํ ํ์ ํ ์ํ๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ต๋๋ค.

๋ค์์ผ๋ก "D 4"๋ฅผ ์ํํ ๋ค์ "C"๋ฅผ ์ํํ ํ์ ํ ์ํ๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ต๋๋ค. 5ํ์ด ํ์ ๋ง์ง๋ง ํ ์ด๋ฏ๋ก, ์ด ๊ฒฝ์ฐ ๋ฐ๋ก ์ ํ์ ์ ํํ๋ ์ ์ ์ฃผ์ํฉ๋๋ค.

๋ค์์ผ๋ก "U 2"๋ฅผ ์ํํ๋ฉด ํ์ฌ ์ ํ๋ ํ์ 2ํ์ด ๋ฉ๋๋ค.

์ ์ํ์์ "Z"๋ฅผ ์ํํ  ๊ฒฝ์ฐ ๊ฐ์ฅ ์ต๊ทผ์ ์ ๊ฑฐ๋ "๋ผ์ด์ธ"์ด ์ ํ ํ์ด ์๋๋๋ก ๋ณต๊ตฌ๋ฉ๋๋ค.

๋ค์ํ๋ฒ "Z"๋ฅผ ์ํํ๋ฉด ๊ทธ ๋ค์์ผ๋ก ์ต๊ทผ์ ์ ๊ฑฐ๋ "์ฝ"์ด ์ ํ ํ์ด ์๋๋๋ก ๋ณต๊ตฌ๋ฉ๋๋ค. ์ด๋, ํ์ฌ ์ ํ๋ ํ์ ๋ฐ๋์ง ์๋ ์ ์ ์ฃผ์ํ์ธ์.

์ด๋, ์ต์ข
 ํ์ ์ํ์ ์ฒ์ ์ฃผ์ด์ง ํ์ ์ํ๋ฅผ ๋น๊ตํ์ฌ ์ญ์ ๋์ง ์์ ํ์ "O", ์ญ์ ๋ ํ์ "X"๋ก ํ์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.

์ฒ์ ํ์ ํ ๊ฐ์๋ฅผ ๋ํ๋ด๋ ์ ์ n, ์ฒ์์ ์ ํ๋ ํ์ ์์น๋ฅผ ๋ํ๋ด๋ ์ ์ k, ์ํํ ๋ช ๋ น์ด๋ค์ด ๋ด๊ธด ๋ฌธ์์ด ๋ฐฐ์ด cmd๊ฐ ๋งค๊ฐ๋ณ์๋ก ์ฃผ์ด์ง ๋, ๋ชจ๋ ๋ช ๋ น์ด๋ฅผ ์ํํ ํ ํ์ ์ํ์ ์ฒ์ ์ฃผ์ด์ง ํ์ ์ํ๋ฅผ ๋น๊ตํ์ฌ ์ญ์ ๋์ง ์์ ํ์ O, ์ญ์ ๋ ํ์ X๋ก ํ์ํ์ฌ ๋ฌธ์์ด ํํ๋ก return ํ๋๋ก solution ํจ์๋ฅผ ์์ฑํด์ฃผ์ธ์.
์ ํ์ฌํญ
5 โค n โค 1,000,000
0 โค k < n
1 โค cmd์ ์์ ๊ฐ์ โค 200,000
"U X", "D X", "C", "Z" ์ค ํ๋์
๋๋ค.cmd์ ๋ฑ์ฅํ๋ ๋ชจ๋  X๋ค์ ๊ฐ์ ํฉ์น ๊ฒฐ๊ณผ๊ฐ 1,000,000 ์ดํ์ธ ๊ฒฝ์ฐ๋ง ์
๋ ฅ์ผ๋ก ์ฃผ์ด์ง๋๋ค."์ด๋ฆ" ์ด์ ์ฌ์ฉํ์์ผ๋, "์ด๋ฆ"์ด์ ๋ด์ฉ์ด ์ค์  ๋ฌธ์ ๋ฅผ ํธ๋ ๊ณผ์ ์ ํ์ํ์ง๋ ์์ต๋๋ค. "์ด๋ฆ"์ด์๋ ์๋ก ๋ค๋ฅธ ์ด๋ฆ๋ค์ด ์ค๋ณต์์ด ์ฑ์์ ธ ์๋ค๊ณ  ๊ฐ์ ํ๊ณ  ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ์ฃผ์ธ์.ํ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ ์ด๋์ ์ ๋ ฅ์ผ๋ก ์ฃผ์ด์ง์ง ์์ต๋๋ค.
์๋๋๋ก ๋ณต๊ตฌํ ํ์ด ์์ ๋(์ฆ, ์ญ์ ๋ ํ์ด ์์ ๋) "Z"๊ฐ ๋ช ๋ น์ด๋ก ์ฃผ์ด์ง๋ ๊ฒฝ์ฐ๋ ์์ต๋๋ค.
์ ๋ต์ ํ์ 0ํ๋ถํฐ n - 1ํ๊น์ง์ ํด๋น๋๋ O, X๋ฅผ ์์๋๋ก ์ด์ด๋ถ์ธ ๋ฌธ์์ด ํํ๋ก return ํด์ฃผ์ธ์.
์ ํ์ฑ ํ ์คํธ ์ผ์ด์ค ์ ํ ์ฌํญ
5 โค n โค 1,000
1 โค cmd์ ์์ ๊ฐ์ โค 1,000
ํจ์จ์ฑ ํ
์คํธ ์ผ์ด์ค ์ ํ ์ฌํญ
์ฃผ์ด์ง ์กฐ๊ฑด ์ธ ์ถ๊ฐ ์ ํ์ฌํญ ์์ต๋๋ค.
์ ์ถ๋ ฅ ์
| n | k | cmd | result | 
|---|---|---|---|
| 8 | 2 | ["D 2","C","U 3","C","D 4","C","U 2","Z","Z"] | "OOOOXOOO" | 
| 8 | 2 | ["D 2","C","U 3","C","D 4","C","U 2","Z","Z","U 1","C"] | "OOXOXOOO" | 
์ ์ถ๋ ฅ ์ ์ค๋ช
๋ฌธ์ ์ ์์์ ๊ฐ์ต๋๋ค.
๋ค์์ 9๋ฒ์งธ ๋ช ๋ น์ด๊น์ง ์ํํ ํ์ ํ ์ํ์ด๋ฉฐ, ์ด๋ ์ ์ถ๋ ฅ ์ #1๊ณผ ๊ฐ์ต๋๋ค.

10๋ฒ์งธ ๋ช
๋ น์ด "U 1"์ ์ํํ๋ฉด "์ดํผ์น"๊ฐ ์ ํ 2ํ์ด ์ ํ๋๋ฉฐ, ๋ง์ง๋ง ๋ช
๋ น์ด "C"๋ฅผ ์ํํ๋ฉด ์ ํ๋ ํ์ ์ญ์ ํ๊ณ , ๋ฐ๋ก ์๋ ํ์ด์๋ "์ ์ด์ง"๊ฐ ์ ํ ํ์ ์ ํํฉ๋๋ค.

๋ฐ๋ผ์ ์ฒ์ ์ฃผ์ด์ง ํ์ ์ํ์ ์ต์ข ํ์ ์ํ๋ฅผ ๋น๊ตํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.

์ ํ์๊ฐ ์๋ด
๋์ ํ์ด
ํด๋น ๋ฌธ์ ๋ ์๋ฐฉํฅ ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ฅผ ๊ตฌํํ ์ ์๋๋๊ฐ ๊ด๊ฑด์ด ๋๋ค.
function solution(n, k, cmd) {
    let arr = Array(n).fill().map((_,i) => i)
    const deleted = []
    let select = k
    const result = []
    cmd.forEach(ord => {
        switch(ord[0]) {
            case 'D':
                select+=Number(ord[2])
                break
            case 'C':
                deleted.push([arr.splice(select,1)[0],select])
                if(select > arr.length) {
                    select = arr.length
                }
                break
            case 'U':
                select-=Number(ord[2])
                break
            case 'Z':
                const [val,idx] = deleted.pop()
                arr.splice(idx,0,val)
                break
        }
    })
    
    return Array(n).fill().map((_,i) => arr.includes(i) ? 'O':'X').join("")
}
ํ์์ ๊ฒฝ์ฐ์๋ ์ ์ฝ๋์ฒ๋ผ ์๋ฐฉํฅ ์ฐ๊ฒฐ์ ์๊ฐํ์ง ์์๋ค๊ฐ ํจ์จ์ฑ ํ ์คํธ๋ฅผ ํ๋๋ ์ฑ๊ณตํ์ง ๋ชปํ์
์๋ฐฉํฅ ๋ฆฌ์คํธ๋ ๊ฐ๋จํ๊ฒ๋ {idx:1, prev: prevNode, next:nextNode} ํ์์ผ๋ก ์ฎ์ฌ์๋ ๋ฐฉ์์ ๋งํ๋ค.
์ฆ ์ฐพ๊ธฐ๋ ์ฝ๊ณ ๋นผ๊ณ ๋ฃ๊ณ ์ ํจ์จ์ด ๋งค์ฐ ๋์์ง
function solution(n, k, cmd) {
    const answer = Array(n).fill('O')
    const root = new Node(0)
    let curNode = root
    let prevNode = root
    for(let i = 1 ; i < n ; i ++) {
        // ์ฐ๊ฒฐ๋ ๋
ธ๋ ๋ฆฌ์คํธ ์์ฑ
        const newNode = new Node(i, prevNode)
        prevNode.next = newNode
        prevNode = newNode
        
        // ์ ํ๋์๋ค๋ฉด
        if(i === k) {
            curNode = newNode
        }
    }
    
    const deleted = []
    cmd.forEach((order) => {
        const [ord, val] = order.split(' ')
        let i = 0
        switch(ord) {
            case 'U':
                while(i < val && curNode.prev) {
                    curNode = curNode.prev
                    i++
                }
                break
            case 'D':
                while(i < val && curNode.next) {
                    curNode = curNode.next
                    i++
                }
                break
            case 'C':
                deleted.push(curNode)
                const prev = curNode.prev
                const next = curNode.next
                if(prev && next) {
                    prev.next = next
                    next.prev = prev
                    curNode = next
                } else if (prev) {
                    prev.next = null
                    curNode = prev
                } else if (next) {
                    next.prev = null
                    curNode = next
                }
                break
            case 'Z':
                const node = deleted.pop()
                const prevNode = node.prev
                const nextNode = node.next
                if(prevNode) {
                    prevNode.next = node
                }
                if(nextNode) {
                    nextNode.prev = node
                }
                break
        }
    })
    
    deleted.forEach(node => {
        answer[node.idx] = 'X'
    })
    return answer.join('')
    return 
}
function Node(idx,prevNode) {
    this.idx = idx
    this.prev = prevNode
    this.next
}