Sword finger Offer II 055. Binary search tree iterator 173. Binary search tree iterator (Java / C / C + + / Python / go / trust)

Thank you very much for reading this article~
Welcome[ 👍 [like][ ⭐ Collection][ 📝 [comments]~
It's not hard to give up, but it must be cool to insist~
I hope all of us can make a little progress every day~
This paper consists of White hat of the second leader: https://le-yi.blog.csdn.net/ Blog originality~

Sword finger Offer II 055. Binary search tree iterator 173. Binary search tree iterator:

Implement a binary search tree iterator class BSTIterator, which represents an iterator that traverses the binary search tree (BST) in medium order:

  • BSTIterator(TreeNode root) initializes an object of the BSTIterator class. The root node of BST is given as part of the constructor. The pointer should be initialized to a number that does not exist in the BST and is less than any element in the BST.
  • boolean hasNext() returns true if there is a number traversing to the right of the pointer; Otherwise, false is returned.
  • int next() moves the pointer to the right and returns the number at the pointer.

Note that the pointer is initialized to a number that does not exist in the BST, so the first call to next() will return the smallest element in the BST.

It can be assumed that the next() call is always valid, that is, when next() is called, there is at least one next number in the middle order traversal of BST.

Example 1

input
	inputs = ["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"]
	inputs = [[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]
	
output
	[null, 3, 7, true, 9, true, 15, true, 20, false]

explain
	BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]);
	bSTIterator.next();    // Return 3
	bSTIterator.next();    // Return 7
	bSTIterator.hasNext(); // Return True
	bSTIterator.next();    // Return to 9
	bSTIterator.hasNext(); // Return True
	bSTIterator.next();    // Return to 15
	bSTIterator.hasNext(); // Return True
	bSTIterator.next();    // Return to 20
	bSTIterator.hasNext(); // Return False

Tips

  • The number of nodes in the tree is in the range [1, 105]
  • 0 <= Node.val <= 106
  • The maximum number of calls to hasNext and next operations is 105

Advanced

  • Can you design a solution that meets the following conditions? The next() and hasNext() operations share the time complexity of O(1) and use O(h) memory. Where h is the height of the tree.

analysis

  • This algorithm test is from the binary search tree 1 From small to large, that is, middle order traversal.
  • You can complete the traversal directly during initialization, put the value into data structures such as queues, and then the value and empty judgment will be very fast.
  • However, there is a disadvantage of completing the traversal during initialization, that is, if the tree is large but the value acquisition is relatively small, the initial initialization is a waste (the reason is the same as the lazy mode of data delayed loading and singleton mode), so we can allocate the traversal to each value operation.

Problem solution

java

class BSTIterator {
    private TreeNode        cur;
    private Deque<TreeNode> stack;

    public BSTIterator(TreeNode root) {
        cur = root;
        stack = new LinkedList<TreeNode>();
    }

    public int next() {
        while (cur != null) {
            stack.push(cur);
            cur = cur.left;
        }
        cur = stack.pop();
        int val = cur.val;
        cur = cur.right;
        return val;
    }

    public boolean hasNext() {
        return cur != null || !stack.isEmpty();
    }
}

c

typedef struct {
    struct TreeNode *cur;
    struct StackTreeNode *stack[100000];
    int stackSize;
} BSTIterator;


BSTIterator *bSTIteratorCreate(struct TreeNode *root) {
    BSTIterator *iterator = malloc(sizeof(BSTIterator));
    iterator->cur = root;
    iterator->stackSize = 0;
    return iterator;
}

int bSTIteratorNext(BSTIterator *obj) {
    while (obj->cur != NULL) {
        obj->stack[(obj->stackSize)++] = obj->cur;
        obj->cur = obj->cur->left;
    }
    obj->cur = obj->stack[--(obj->stackSize)];
    int val = obj->cur->val;
    obj->cur = obj->cur->right;
    return val;
}

bool bSTIteratorHasNext(BSTIterator *obj) {
    return obj->cur != NULL || obj->stackSize;
}

void bSTIteratorFree(BSTIterator *obj) {
    free(obj);
}

c++

class BSTIterator {
private:
    TreeNode *cur;
    stack<TreeNode *> stacks;
public:
    BSTIterator(TreeNode *root) : cur(root) {
    }

    int next() {
        while (cur != nullptr) {
            stacks.push(cur);
            cur = cur->left;
        }
        cur = stacks.top();
        stacks.pop();
        int val = cur->val;
        cur = cur->right;
        return val;
    }

    bool hasNext() {
        return cur != nullptr || !stacks.empty();
    }
};

python

class BSTIterator:

    def __init__(self, root: TreeNode):
        self.cur = root
        self.stack = []


    def next(self) -> int:
        while self.cur:
            self.stack.append(self.cur)
            self.cur = self.cur.left
        self.cur = self.stack.pop()
        val = self.cur.val
        self.cur = self.cur.right
        return val

    def hasNext(self) -> bool:
        return True if self.cur or self.stack else False

go

type BSTIterator struct {
	cur   *TreeNode
	stack []*TreeNode
}

func Constructor(root *TreeNode) BSTIterator {
	return BSTIterator{cur: root}
}

func (this *BSTIterator) Next() int {
	for this.cur != nil {
		this.stack = append(this.stack, this.cur)
		this.cur = this.cur.Left
	}
	this.cur, this.stack = this.stack[len(this.stack)-1], this.stack[:len(this.stack)-1]
	val := this.cur.Val
	this.cur = this.cur.Right
	return val
}

func (this *BSTIterator) HasNext() bool {
	return this.cur != nil || len(this.stack) > 0
}

rust

use std::{rc::Rc, cell::RefCell};
struct BSTIterator {
  cur: Option<Rc<RefCell<TreeNode>>>,
  stack: Vec<Rc<RefCell<TreeNode>>>
}

impl BSTIterator {

  fn new(root: Option<Rc<RefCell<TreeNode>>>) -> Self {
    BSTIterator {
      cur: root.clone(),
      stack: Vec::new()
    }
  }

  fn next(&mut self) -> i32 {
    while let Some(n) = self.cur.clone() {
      self.stack.push(n.clone());
      self.cur = n.borrow().left.clone();
    };
    self.cur = self.stack.pop();
    let val = self.cur.clone().unwrap().borrow().val;
    self.cur = self.cur.clone().unwrap().borrow().right.clone();
    val
  }

  fn has_next(&self) -> bool {
    self.cur.is_some() || !self.stack.is_empty()
  }
}

Original title portal: https://leetcode-cn.com/problems/kTOapQ/

Original title portal: https://leetcode-cn.com/problems/binary-search-tree-iterator/

  1. Binary Search Tree (also: Binary Search Tree, binary sort tree) is either an empty tree or a binary tree with the following properties: if its left subtree is not empty, the values of all nodes on the left subtree are less than the values of its root node; If its right subtree is not empty, the values of all nodes on the right subtree are greater than those of its root node; Its left and right subtrees are also binary sort trees. As a classical data structure, Binary Search Tree not only has the characteristics of fast insertion and deletion of linked list, but also has the advantage of fast search of array; Therefore, it is widely used. For example, this data structure is generally used in file system and database system for efficient sorting and retrieval. ↩ī¸Ž

Tags: Python Java C Go Rust

Posted on Thu, 04 Nov 2021 19:54:27 -0400 by web_noob