173. Binary Search Tree Iterator
leetcode medium
Task
Реализуйте класс BSTIterator, который представляет итератор по обходу бинарного дерева поиска (BST) в порядке in-order:
BSTIterator(TreeNode root): Инициализирует объект класса BSTIterator. Корень BST передается в качестве параметра конструктора. Указатель должен быть инициализирован на несуществующее число, меньшее любого элемента в BST.
boolean hasNext(): Возвращает true, если в обходе справа от указателя существует число, иначе возвращает false.
int next(): Перемещает указатель вправо, затем возвращает число на указателе.
Обратите внимание, что при инициализации указателя на несуществующее наименьшее число, первый вызов next() вернет наименьший элемент в BST.
Можно предположить, что вызовы next() всегда будут допустимы. То есть, при вызове next() в обходе всегда будет хотя бы одно следующее число.
Пример:
Input
["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"]
[[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]
Output
[null, 3, 7, true, 9, true, 15, true, 20, false]
Explanation
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 9
bSTIterator.hasNext(); // return True
bSTIterator.next(); // return 15
bSTIterator.hasNext(); // return True
bSTIterator.next(); // return 20
bSTIterator.hasNext(); // return False
C# solution
matched/originalpublic class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; left = null; right = null; }
}
public class BSTIterator {
private List<int> nodesSorted;
private int index;
private void Inorder(TreeNode root) {
if (root == null) return;
Inorder(root.left);
nodesSorted.Add(root.val);
Inorder(root.right);
}
public BSTIterator(TreeNode root) {
nodesSorted = new List<int>();
index = -1;
Inorder(root);
}
public int Next() {
return nodesSorted[++index];
}
public bool HasNext() {
return index + 1 < nodesSorted.Count;
}
}C++ solution
auto-draft, review before submit#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; left = null; right = null; }
}
public class BSTIterator {
private List<int> nodesSorted;
private int index;
private void Inorder(TreeNode root) {
if (root == null) return;
Inorder(root.left);
nodesSorted.push_back(root.val);
Inorder(root.right);
}
public BSTIterator(TreeNode root) {
nodesSorted = new List<int>();
index = -1;
Inorder(root);
}
public int Next() {
return nodesSorted[++index];
}
public bool HasNext() {
return index + 1 < nodesSorted.size();
}
}Java solution
matched/originalclass BSTIterator {
ArrayList<Integer> nodesSorted;
int index;
public BSTIterator(TreeNode root) {
this.nodesSorted = new ArrayList<Integer>();
this.index = -1;
this._inorder(root);
}
private void _inorder(TreeNode root) {
if (root == null) {
return;
}
this._inorder(root.left);
this.nodesSorted.add(root.val);
this._inorder(root.right);
}
public int next() {
return this.nodesSorted.get(++this.index);
}
public boolean hasNext() {
return this.index + 1 < this.nodesSorted.size();
}
}JavaScript solution
matched/originalclass TreeNode {
constructor(val) {
this.val = val;
this.left = null;
this.right = null;
}
}
class BSTIterator {
constructor(root) {
this.nodesSorted = [];
this.index = -1;
this._inorder(root);
}
_inorder(root) {
if (root === null) {
return;
}
this._inorder(root.left);
this.nodesSorted.push(root.val);
this._inorder(root.right);
}
next() {
return this.nodesSorted[++this.index];
}
hasNext() {
return this.index + 1 < this.nodesSorted.length;
}
}Python solution
matched/originalclass TreeNode:
def __init__(self, x: int):
self.val = x
self.left = None
self.right = None
class BSTIterator:
def __init__(self, root: TreeNode):
self.nodes_sorted = []
self.index = -1
self._inorder(root)
def _inorder(self, root: TreeNode) -> None:
if not root:
return
self._inorder(root.left)
self.nodes_sorted.append(root.val)
self._inorder(root.right)
def next(self) -> int:
self.index += 1
return self.nodes_sorted[self.index]
def hasNext(self) -> bool:
return self.index + 1 < len(self.nodes_sorted)Go solution
matched/originalpackage main
import "fmt"
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
type BSTIterator struct {
nodesSorted []int
index int
}
func Constructor(root *TreeNode) BSTIterator {
iterator := BSTIterator{nodesSorted: []int{}, index: -1}
iterator.inorder(root)
return iterator
}
func (this *BSTIterator) inorder(root *TreeNode) {
if root == nil {
return
}
this.inorder(root.Left)
this.nodesSorted = append(this.nodesSorted, root.Val)
this.inorder(root.Right)
}
func (this *BSTIterator) Next() int {
this.index++
return this.nodesSorted[this.index]
}
func (this *BSTIterator) HasNext() bool {
return this.index+1 < len(this.nodesSorted)
}
func main() {
root := &TreeNode{7,
&TreeNode{3, nil, nil},
&TreeNode{15,
&TreeNode{9, nil, nil},
&TreeNode{20, nil, nil}}}
iterator := Constructor(root)
fmt.Println(iterator.Next())
fmt.Println(iterator.HasNext())
fmt.Println(iterator.Next())
fmt.Println(iterator.HasNext())
fmt.Println(iterator.Next())
fmt.Println(iterator.HasNext())
fmt.Println(iterator.Next())
fmt.Println(iterator.HasNext())
fmt.Println(iterator.Next())
fmt.Println(iterator.HasNext())
}Explanation
Algorithm
1️⃣
Инициализируйте пустой массив, который будет содержать узлы бинарного дерева поиска в отсортированном порядке.
2️⃣
Мы обходим бинарное дерево поиска в порядке in-order и для каждого узла, который обрабатываем, добавляем его в наш массив узлов. Обратите внимание, что перед обработкой узла сначала нужно обработать (или рекурсивно вызвать) его левое поддерево, а после обработки узла — его правое поддерево.
3️⃣
Когда у нас будут все узлы в массиве, нам просто нужен указатель или индекс в этом массиве для реализации двух функций
next
и
hasNext
. Всякий раз, когда вызывается
hasNext
, мы просто проверяем, достиг ли индекс конца массива или нет. При вызове функции
next
мы просто возвращаем элемент, на который указывает индекс. Также, после вызова функции
next
, мы должны переместить индекс на один шаг вперед, чтобы имитировать прогресс нашего итератора.
😎