πŸ’‘λ°ν¬ κΈ°λ³Έ κ°œλ…

  • μŠ€νƒ(stack)κ³Ό 큐(Queue)의 연산을 λͺ¨λ‘ 가지고 μžˆλŠ” 볡합 μžλ£Œν˜• 자료ꡬ쑰
  • 데크(Deque) : Double Ended Queue의 μ€„μž„λ§λ‘œμ„œ μ–‘μͺ½ 끝 데이터λ₯Ό λͺ¨λ‘ μΆ”μΆœν•  수 μžˆλŠ” 큐의 ν˜•νƒœ
  • 데크 μžλ£Œκ΅¬μ‘°λŠ” μ–‘μͺ½ λμ—μ„œ μ‚½μž… μ‚­μ œ λͺ¨λ‘ κ°€λŠ₯ν•˜λ‹€
  • νŒŒμ΄μ¬μ—μ„œλŠ” 데크 자료ꡬ쑰λ₯Ό collections 라이브러리λ₯Ό ν™œμš©ν•˜μ—¬ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€
  • 데크 μžλ£Œκ΅¬μ‘°λŠ” 이쀑 μ—°κ²° 리슀트둜 κ΅¬ν˜„ν•˜λŠ” 것이 μœ μš©ν•˜λ‹€. 포인터λ₯Ό 2개 ν™œμš©ν•΄μ„œ μ•žλ’€μ—μ„œ μ‚½μž… μ‚­μ œκ°€ κ°€λŠ₯ν•˜λ‹€.

 

πŸ’‘λ°ν¬ 자료ꡬ쑰 직접 κ΅¬ν˜„

  • λ‹€μŒ 연산을 μ§€μ›ν•˜λŠ” μ›ν˜• 데크λ₯Ό λ””μžμΈν•˜λΌ

    • MyCircularDeque(k: int) - kκ°’μœΌλ‘œ μ΅œλŒ€ μ›ν˜• 데크의 μ‚¬μ΄μ¦ˆ μ΄ˆκΈ°ν™”ν•˜κΈ°
    • insertFront(value: int) - μž…λ ₯κ°’(value)을 데크의 μ•žμͺ½μ— μ‚½μž…ν•˜κ³ , μ„±κ³΅ν–ˆλ‹€λ©΄ True, μ‹€νŒ¨ν–ˆλ‹€λ©΄ False λ°˜ν™˜ν•˜κΈ°
    • insertLast(vlaue: int) - μž…λ ₯κ°’(value)을 데크의 λ’€μͺ½μ— μ‚½μž…ν•˜κ³ , μ„±κ³΅ν–ˆλ‹€λ©΄ True, μ‹€νŒ¨ν–ˆλ‹€λ©΄ False 
    • deleteFront() - 데크 자료ꡬ쑰의 맨 μ•žμ˜ 값을 μ‚­μ œν•˜κ³ , μ„±κ³΅ν–ˆλ‹€λ©΄ True, μ‹€νŒ¨ν–ˆλ‹€λ©΄ False 
    • deleteLast() - 데크 자료ꡬ쑰의 맨 λ’€μ˜ 값을 μ‚­μ œν•˜κ³ , μ„±κ³΅ν–ˆλ‹€λ©΄ True, μ‹€νŒ¨ν–ˆλ‹€λ©΄ False 
    • getFront() - 데크 자료ꡬ쑰의 맨 μ•žμ˜ 값을 λ°˜ν™˜ν•˜λ˜ λ§Œμ•½ 값이 μ—†λ‹€λ©΄ -1을 λ°˜ν™˜
    • getLast() - 데크 자료ꡬ쑰의 맨 λ’€μ˜ 값을 λ°˜ν™˜ν•˜λ˜ λ§Œμ•½ 값이 μ—†λ‹€λ©΄ -1을 λ°˜ν™˜
    • isEmpty() - 데크 자료ꡬ쑰의 값이 λΉ„μ–΄μžˆλ‹€λ©΄ True, μ•„λ‹ˆλ©΄ False
    • isFull() - 데크 자료ꡬ쑰의 값이 가득 μ°¨ μžˆλ‹€λ©΄ True, μ•„λ‹ˆλ©΄ False

  • 이쀑 μ—°κ²° 리슀트λ₯Ό ν™œμš©ν•˜μ—¬ μ›ν˜• 데크 자료ꡬ쑰 κ΅¬ν˜„

 

πŸ’» μ›ν˜• 데크 μ΄ˆκΈ°ν™”

class MyCircularDeque(object):

    def __init__(self, k):
        """
        :type k: int
        """
        # μ™Όμͺ½(head), 였λ₯Έμͺ½(tail) index 역할을 ν•  μ—°κ²°λ¦¬μŠ€νŠΈ μ •μ˜
        self.head, self.tail = ListNode(None), ListNode(None)
        self.head.right, self.tail.left = self.tail, self.head
        
        # μ΅œλŒ€ 길이와 ν˜„μž¬ 길이 정보λ₯Ό 담을 λ³€μˆ˜ μ •μ˜
        self.maxlen, self.length = k, 0

 

πŸ’» μ›ν˜• 데크 데이터 μΆ”κ°€ λ‚΄μž₯ν•¨μˆ˜

def _add(self, node: ListNode, new: ListNode):
	
    # μ‚½μž…ν•  μ—°κ²° 리슀트의 κΈ°μ‘΄ 였λ₯Έμͺ½ 값을 μ •μ˜ν•œλ‹€
    # μ•„λ§ˆ None 값일 κ²ƒμœΌλ‘œ μ˜ˆμƒν•œλ‹€.
    # front : n --> self.head.right.right --> self.tail.right
    # last  n --> self.tail.left.right  --> self.head.right
    n = node.right 
    
    # μ—°κ²° 리슀트의 였λ₯Έμͺ½ 값을 μƒˆλ‘œμš΄ κ°’μœΌλ‘œ μ—…λ°μ΄νŠΈν•œλ‹€.
    # front : self.head.right.right == ListNode(value)
    # last  : self.tail.left.right  == ListNode(value)
    node.right = new
    
    # μƒˆλ‘œμš΄ λ…Έλ“œμ˜ left 값은 κΈ°μ‘΄ node의 κ°’μœΌλ‘œ μ •μ˜ν•˜κ³  (즉, head μ—­ν• )
    # right 값은 μœ„μ—μ„œ λ”°λ‘œ μ •μ˜ν•œ None κ°’μœΌλ‘œ μ •μ˜ν•΄μ€€λ‹€
    # head - new - None
    new.left, new.right = node, n
    
    # 그리고 n의 left 값을 μƒˆλ‘œμš΄ κ°’μœΌλ‘œ μ •μ˜ν•œλ‹€.
    # front : n = self.head.right.right
    # last  : n = self.tail.left.right
    n.left = new

 

πŸ’» μ›ν˜• 데크 데이터 μ‚­μ œ λ‚΄μž₯ν•¨μˆ˜

def _del(self, node: ListNode):
        
    # ? None 값을 미리 μ •μ˜ν•˜λŠ”κ±΄κ°€?
    n = node.right.right

    # μ—…λ°μ΄νŠΈ
    node.right = n

    # ? n의 μ™Όμͺ½ 값을 μž…λ ₯ν•œ ν¬μΈν„°μ˜ κ°’μœΌλ‘œ μ •μ˜? μ™œ?
    n.left = node

 

πŸ’» μ›ν˜• 데크 μ•žμͺ½, λ’€μͺ½ 데이터 μΆ”κ°€

def insertFront(self, value):
    """
    :type value: int
    :rtype: bool
    """
    
    # ν˜„μž¬ 길이 정보λ₯Ό ν™•μΈν•œλ‹€
    # ν˜„μž¬ 길이가 μ΅œλŒ€ 길이와 κ°™λ‹€λ©΄ 더이상 μ‚½μž…ν•  수 없기에 Falseλ₯Ό return
    if self.length == self.maxlen:
    	return False
    
    # ν˜„μž¬ 길이가 아직 μ΅œλŒ€ 길이에 λ„λ‹¬ν•˜μ§€ μ•Šμ•˜λ‹€λ©΄ 데이터λ₯Ό μ‚½μž…ν•  것이기에
    # ν˜„μž¬ 길이λ₯Ό μ—…λ°μ΄νŠΈ ν•΄μ€€λ‹€
    self.length += 1
    
    # value값을 μ›ν˜• 데크 μžλ£Œκ΅¬μ‘°μ— μΆ”κ°€ν•΄μ€€λ‹€.
    # λ‚΄μž₯ ν•¨μˆ˜ _add λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  μ˜ˆμ •
    # value 값을 μ—°κ²°λ¦¬μŠ€νŠΈ 자료ꡬ쑰 ν˜•νƒœμ— λ‹΄μ•„μ„œ μΆ”κ°€ν•œλ‹€.
    self._add(self.head, ListNode(value))
    
    
def insertLast(self, value):
    """
    :type value: int
    :rtype: bool
    """

    # ν˜„μž¬ 길이 ν™•μΈν•˜μ—¬ μ΅œλŒ€ 길이에 λ„λ‹¬ν–ˆλ‹€λ©΄ False return
    if self.length == self.maxlen:
        return False

    # ν˜„μž¬ 길이 μ—…λ°μ΄νŠΈ
    self.length += 1

    # λ’€μͺ½μ— 값을 μ‚½μž…ν•  λ•ŒλŠ” self.tail 포인터λ₯Ό ν™œμš©
    # self.tail.left == μ΄ˆκΈ°μ— self.head둜 μ§€μ •ν–ˆμŒ
    # μ—…λ°μ΄νŠΈ 될 κ²ƒμœΌλ‘œ μ˜ˆμƒν•˜λ©΄μ„œ μž‘μ—…
    self._add(self.tail.left, ListNode(value))

 

πŸ’» μ›ν˜• 데크 μ•žμͺ½, λ’€μͺ½ 데이터 μ‚­μ œ

def deleteFront(self):
    # μ‚­μ œν•  값이 μ—†λ‹€λ©΄ False return
    if self.length == 0:
        return False

    # ν˜„μž¬ 길이 업데이터
    self.length -= 1

    # μ‚­μ œ 둜직
    self._del(self.head)

    return True


def deleteLast(self):
    # μ‚­μ œν•  값이 μ—†λ‹€λ©΄ False return
    if self.length == 0:
        return False

    # ν˜„μž¬ 길이 업데이터
    self.length -= 1

    # μ‚­μ œ 둜직
    # λ’· 뢀뢄을 μ‚­μ œν•  λ•ŒλŠ” tail 포인터λ₯Ό ν™œμš©ν•˜λŠ”λ°
    # μ™œ left.left의 값을 λ„£μ–΄μ£ΌλŠ”μ§€ κΆκΈˆν•¨
    self._del(self.tail.left.left)

 

πŸ’» μ›ν˜• 데크 데이터 μƒνƒœ 확인 및 νŒλ³„

def getFront(self):
    """
    :rtype: int
    맨 μ•žμ˜ κ°’ λ°˜ν™˜
    """
    return self.head.right.val if self.length else -1


def getRear(self):
    """
    :rtype: int
    맨 λ’€ κ°’ λ°˜ν™˜
    """
    return self.tail.left.val if self.length else -1


def isEmpty(self):
    """
    :rtype: bool
    데크 자료ꡬ쑰의 값이 λΉ„μ–΄ μžˆλŠ”μ§€ νŒλ³„
    """
    return self.length == 0


def isFull(self):
    """
    :rtype: bool
    데크 자료ꡬ쑰의 값이 가득 μ°¨ μžˆλŠ”μ§€ νŒλ³„
    """
    return self.length == self.maxlen

+ Recent posts