Binary Search Tree Iterator

Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.node

Calling next() will return the next smallest number in the BST.app

Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.this

二叉查找樹的一道設計題。可是其實思路比較難想。spa

首先須要均攤時間複雜度爲O(1),使用O(h)複雜度度,其實很容易想到使用棧來作,可是如何來作比較難想。首先返回一個遞增的序列,仍是中序遍歷。可是直接先用中序遍歷存儲全部結點,以後再返回的空間複雜度爲O(n),不符合題目O(h)的空間複雜度的要求。因此該題的作法應該在next中給棧增長元素。設置一個self.cur來代表當前指向的結點。可是該結點不必定是當前須要返回的元素。實際上是要返回以該結點爲根的子樹中的最左結點。好比開始的時候 self.cur = root。可是須要尋找以root爲根的最左結點。爲了之後的回溯方便,咱們須要在找尋最左結點時保存遍歷到的結點。在遍歷到最左結點以後,返回該結點。則爲了下一步的next準備咱們把self.cur設置爲返回結點的右孩子。這符合中序遍歷的作法。若是該右孩子不存在,則利用棧中元素進行回溯(彈出棧),這個回溯到的點是直接須要返回的值,時間複雜度O(1)。若是該右孩子爲葉子結點,則直接返回該葉子結點,時間複雜度也爲O(1)。最壞的狀況是該右孩子有子樹,則須要找到該子樹中的最左結點。這個的時間複雜度不是O(1)。可是每一個結點一次被壓棧,一次被彈出,其實平均的時間複雜度爲O(1)。代碼以下:設計

class BSTIterator(object):
    def __init__(self, root):
        """
        :type root: TreeNode
        """
        self.stack = []
        self.cur = root

    def hasNext(self):
        """
        :rtype: bool
        """
        return len(self.stack)>0 or self.cur != None
    
    def next(self):
        """
        :rtype: int
        """
        while self.cur: 
            self.stack.append(self.cur)
            self.cur = self.cur.left
        self.cur = self.stack.pop() #self.cur now is the left most node.
        node = self.cur
        self.cur = self.cur.right
        return node.val

 簡單作法:code

其實就是找二叉查找樹的後繼blog

# Definition for a  binary tree node
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class BSTIterator(object):
    def __init__(self, root):
        """
        :type root: TreeNode
        """
        self.stack = []
        cur = root
        while cur:
            self.stack.append(cur)
            cur = cur.left

    def hasNext(self):
        """
        :rtype: bool
        """
        return len(self.stack)>0
    
    def next(self):
        """
        :rtype: int
        """
        node = self.stack.pop()
        cur = node.right
        while cur:
            self.stack.append(cur)
            cur = cur.left
        return node.val
        
# Your BSTIterator will be called like this:
# i, v = BSTIterator(root), []
# while i.hasNext(): v.append(i.next())

這題的followup 若是結點有屬性parent記錄父結點,要求用O(1)的空間解:it

class BSTIteratorN(object):
    def __init__(self, root):
        """
        :type root: TreeNode
        """
        self.prev = None
        self.cur = root
        while self.cur and self.cur.left:
            self.cur = self.cur.left

    def hasNext(self):
        """
        :rtype: bool
        """
        return self.cur != None

    def next(self):
        """
        :rtype: int
        """
        node = self.cur
        if self.prev == None:
            self.cur = self.cur.parent
        else:
            if self.prev == self.cur.parent:  #最後從這裏結束遍歷
                self.cur = self.cur.parent.parent
#注意這裏不能直接驗證是否和左子結點相等,存在右子樹徹底走完,向上跳兩級父結點的狀況。此時也須要遍歷當前結點的右子樹。可是prev不是當前結點的左結點
elif self.prev != self.cur.right: self.cur = self.cur.right while self.cur and self.cur.left: self.cur = self.cur.left self.prev = node return node.val
相關文章
相關標籤/搜索