[μ€μννΈ μκ³ λ¦¬μ¦] νλ‘κ·Έλλ¨Έμ€: ν νΈμ§
λ¬Έμ
https://programmers.co.kr/learn/courses/30/lessons/81303
μ½λ©ν μ€νΈ μ°μ΅ - ν νΈμ§
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"
programmers.co.kr
[λ³Έ λ¬Έμ λ μ νμ±κ³Ό ν¨μ¨μ± ν μ€νΈ κ°κ° μ μκ° μλ λ¬Έμ μ λλ€.]
μ λ¬΄μ© μννΈμ¨μ΄λ₯Ό κ°λ°νλ λλμ¦μμ€μ μΈν΄μΈ μλͺ¬λλ λͺ λ Ήμ΄ κΈ°λ°μΌλ‘ νμ νμ μ ν, μμ , 볡ꡬνλ νλ‘κ·Έλ¨μ μμ±νλ κ³Όμ λ₯Ό λ§‘μμ΅λλ€. μΈλΆ μꡬ μ¬νμ λ€μκ³Ό κ°μ΅λλ€
μ κ·Έλ¦Όμμ νλμμΌλ‘ μΉ ν΄μ§ μΉΈμ νμ¬ μ νλ νμ λνλ λλ€. λ¨, ν λ²μ ν νλ§ μ νν μ μμΌλ©°, νμ λ²μ(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 ν¨μλ₯Ό μμ±ν΄μ£ΌμΈμ.
νμ΄
ν¨μ¨μ±κΉμ§ ν΅κ³ΌνκΈ°μ μ΄λ €μ΄ λ¬Έμ μΏμ΅λλ€γ λ€ νΈλλ° 2μκ°μ κ±Έλ¦°κ² κ°λ€μ..
μ΄ λ¬Έμ λ₯Ό ν¨μ¨μ±κΉμ§ ν΅κ³Όνλ €λ©΄ μ λλ‘ O(N) μ΄μμ μκ°λ³΅μ‘λκ° λ°μνλ©΄ μλ©λλ€. κ·Έλμ μλ°©ν₯ λ§ν¬λ 리μ€νΈλ₯Ό μ¬μ©ν΄μΌν©λλ€.
κ·Έλ¦¬κ³ λμμ κΈ°μ‘΄μ λ§ν¬λ 리μ€νΈμλ μ‘°κΈ λ€λ₯΄κ² ꡬμ±ν΄μΌνλ λΆλΆλ€μ΄ μμ΅λλ€.
Node ꡬ쑰
λ¨Όμ , κ° λ Έλκ° μμ μ ν μΈλ±μ€ μ 보λ₯Ό κΈ°μ΅νκ³ μμ΄μΌν©λλ€. λ§μ§λ§μ μ΅μ΄μ νμμ λ¬λΌμ§ λΆλΆλ§μ νμν΄μΌνκΈ° λλ¬Έμ λλ€.
λ°λΌμ λ Έλ μλ£κ΅¬μ‘°λ λ€μμ²λΌ ꡬμ±ν μ μμ΅λλ€.
class Node {
var data: Int?
var next: Node?
var prev: Node?
init(data: Int, next: Node?, prev: Node?) {
self.data = data
self.next = next
self.prev = prev
}
}
dataμλ μΈλ±μ€λ₯Ό λ£κ³ , nextμ prevμ μμ μ λ€μ, μ΄μ λ Έλμ μ°Έμ‘°κ°μ μ μ₯ν©λλ€.
λ§ν¬λ리μ€νΈ
μ΄μ λ§ν¬λ리μ€νΈλ₯Ό ꡬνν΄μΌνλλ°μ, λ§ν¬λ리μ€νΈλ λ€μκ³Ό κ°μ μ 보λ₯Ό κ°μ§κ³ μμ΄μΌν©λλ€.
- μμ λ νμ μ 보 (isDeleted)
- κ°μ₯ μ λ Έλμ ν¬μΈν°(head)
- κ°μ₯ λ§μ§λ§ λ Έλμ ν¬μΈν°(tail)
- νμ¬ κ°λ¦¬ν€κ³ μλ λ Έλ(cursor)
κ·Έλ¦¬κ³ μ΄ λ¬Έμ μμ μ¬μ©νλ μ°μ°μ μ΄ 4 μ’ λ₯μ λλ€.
- μλ‘μ΄ λ Έλ μ½μ νκΈ°
- νμ¬ κ°λ¦¬ν€κ³ μλ λ Έλλ₯Ό μμ νκΈ°
- μμ νλ λ Έλλ₯Ό μλμ리μ 볡μνκΈ°
- νμ¬ κ°λ¦¬ν€κ³ μλ λ Έλλ₯Ό λ³κ²½νκΈ°
λ Έλ μ½μ
λ§ν¬λ리μ€νΈμμ κ°μ₯ μμ λνλ΄λ headλ§μ μ¬μ©νλ©΄ μλ‘μ΄ λ°μ΄ν°λ₯Ό λ£μ λλ§λ€ κ°μ₯ λ§μ§λ§ λ ΈλκΉμ§ νμν΄μΌνλ O(N) μκ°λ³΅μ‘λκ° λ°μνκΈ° λλ¬Έμ tailμ΄λΌλ ν¬μΈν°λ₯Ό μ¬μ©ν΄μ νμ λ§ν¬λ리μ€νΈμ λ§μ§λ§μ κ°λ¦¬ν€λλ‘ νκ³ μλ‘μ΄ λ Έλλ tailμ λ€μ λΆμ¬μ£Όκ³ tailμ μ λ°μ΄νΈ νλ λ°©μμΌλ‘ μ§νν©λλ€. μ΄λ κ² νλ©΄ μ½μ μ°μ°μ O(1)λ§μ λλΌ μ μμ΅λλ€.
mutating func append(data: Int, isInitCursor: Bool) {
let node = Node(data: data, next: nil, prev: nil)
if isInitCursor { cursor = node }
if head == nil {
head = node
tail = node
} else {
node.prev = tail
tail?.next = node
tail = node
}
isDeleted.append(false)
}
λ Έλ μμ
λ Έλμ μμ λ μ΄λ€ νΉμ ν λ Έλλ₯Ό μμ νμ§ μκ³ , νμ¬ κ°λ¦¬ν€κ³ μλ λ Έλλ₯Ό μμ νλ κ²μΌλ‘ μ°μ°μ μνν μ μμ΅λλ€. λ°λΌμ λͺ¨λ λ Έλλ₯Ό νμνμ§ μκ³ cursorμ μ μ₯λ μ°Έμ‘°κ°μ μ°Ύμκ° ν΄λΉ λ Έλμ μ΄μ λ Έλμ λ€μλ Έλλ₯Ό μ°κ²°ν΄μ£Όλ κ²μΌλ‘ μ΄λ²μλ O(1)λ§μ μμ μ°μ°μ μνν©λλ€. κ·Έλ¦¬κ³ μμ κ° λλ μ΄νμλ ν΄λΉ λ Έλκ° κ°μ§κ³ μλ μΈλ±μ€ κ°μ μ¬μ©νμ¬ ν΄λΉ νμ΄ μμ λμμμ μ μ₯ν©λλ€.
mutating func remove() -> Node? {
let delNode = cursor
cursor?.next?.prev = cursor?.prev
cursor?.prev?.next = cursor?.next
cursor = delNode?.next == nil ? delNode?.prev : delNode?.next
isDeleted[delNode!.data!] = true
return delNode
}
λ Έλ 볡μ
λ Έλμ 볡μμ μμ£Ό κ°λ¨νκ² μνν μ μμ΅λλ€. 볡μνλ €κ³ νλ λ Έλκ° κ°μ§κ³ μλ μ΄μ λ Έλμ λ€μλ Έλμ μ°Έμ‘°κ°μ κ·Έλλ‘ μ¬μ©νμ¬ λ³΅μν΄μ€λλ€. κ·Έλ¦¬κ³ μμ λμλ λ Έλκ° λ€μ 볡μλμμμ μ μ₯ν©λλ€.
mutating func restore(node: Node?) {
node?.prev?.next = node
node?.next?.prev = node
isDeleted[node!.data!] = false
}
컀μ μ΄λ
컀μλ₯Ό μ΄λν λλ μ£Όμ΄μ§λ κ°λ§νΌ ν¬μΈν°λ₯Ό μ΄λμμΌμ€λλ€. μλ°©ν₯ λ§ν¬λ리μ€νΈμ΄κΈ° λλ¬Έμ μλ‘ μ¬λΌκ°λλ μ΄μ λ Έλλ€μ νμνκ³ , λ΄λ €κ° λλ λ€μλ Έλλ€μ νμν©λλ€. λ¬Έμ μμ λ²μλ₯Ό λ²μ΄λλ μ΄λμ μ λ ₯λμ§ μλλ€κ³ μ£Όμ΄μ ΈμκΈ° λλ¬Έμ λ°λ‘ μμΈμ²λ¦¬λ₯Ό νμ§ μμλ λ©λλ€. μ΄ μ°μ°μ μ£Όμ΄μ§λ μ΄λκ° xλ§νΌμ O(x) μ°μ°μ΄ μνλ©λλ€.
mutating func moveUp(to amount: Int) {
for _ in 0..<amount {
cursor = cursor?.prev
}
}
mutating func moveDown(to amount: Int) {
for _ in 0..<amount {
cursor = cursor?.next
}
}
λ§μ§λ§μΌλ‘ λͺ¨λ μ°μ°μ μνν λ€μλ μμ λμ΄ μλ λ Έλλ€μ ꡬλΆν΄μ λ¬Έμμ΄λ‘ λ§λ€μ΄ λ°ννλ©΄ ν΄κ²°λ©λλ€!
return table.isDeleted.map({ $0 ? "X" : "O" }).joined(separator: "")
μΉ΄μΉ΄μ€ μΈν΄μ μ½ν μμ μ΄ λ¬Έμ λ₯Ό νλ€κ° μκ°μ΄ μ’ λ£λμλλ°, μ΄λ²μλ μμ μμ² λ§μ μκ°μ΄ κ±Έλ Έμ΅λλ€. κ·Έλλ λλΆμ λ§ν¬λ 리μ€νΈλ λ€μ ꡬνν΄λ³Ό μ μκ³ λ§μ 곡λΆκ° λμμ΅λλ€!
μ½λ