# Encode and Decode Strings

- slug: encode-and-decode-strings
- difficulty: Medium

Design an algorithm to encode **a list of strings** to **a string**. The encoded string is then sent over the network and is decoded back to the original list of strings.

Machine 1 (sender) has the function:

string encode(vector strs) {
  // ... your code
  return encoded\_string;
}

Machine 2 (receiver) has the function:

vector decode(string s) {
  //... your code
  return strs;
}

So Machine 1 does:

string encoded\_string = encode(strs);

and Machine 2 does:

vector strs2 = decode(encoded\_string);

`strs2` in Machine 2 should be the same as `strs` in Machine 1.

Implement the `encode` and `decode` methods.

You are not allowed to solve the problem using any serialize methods (such as `eval`).

**Example 1:**

**Input:** dummy\_input = \[ "Hello ", "World "\]
**Output:** \[ "Hello ", "World "\]
**Explanation:**
Machine 1:
Codec encoder = new Codec();
String msg = encoder.encode(strs);
Machine 1 ---msg---> Machine 2

Machine 2:
Codec decoder = new Codec();
String\[\] strs = decoder.decode(msg);

**Example 2:**

**Input:** dummy\_input = \[ " "\]
**Output:** \[ " "\]

**Constraints:**

*   `1 <= strs.length <= 200`
*   `0 <= strs[i].length <= 200`
*   `strs[i]` contains any possible characters out of `256` valid ASCII characters.

**Follow up:** Could you write a generalized algorithm to work on any possible set of characters?

## A solution in Java

```java
import java.util.ArrayList;
import java.util.List;

public String encode(List<String> strs) {
    StringBuilder encodedString = new StringBuilder();
    for (String s : strs) {
        encodedString.append(s.length()).append('#').append(s);
    }
    return encodedString.toString();
}

public List<String> decode(String s) {
    List<String> strs = new ArrayList<>();
    int i = 0;
    while (i < s.length()) {
        int delimiterPos = s.indexOf('#', i);
        int length = Integer.parseInt(s.substring(i, delimiterPos));
        strs.add(s.substring(delimiterPos + 1, delimiterPos + 1 + length));
        i = delimiterPos + 1 + length;
    }
    return strs;
}
```
The algorithm concatenates each string with its length and a delimiter (in this case '#'). For example, ["Hello ", "World "] would be encoded into "6#Hello 6#World " (6 is the length of both "Hello " and "World ").

When decoding, the receiving side searches for the delimiter and extracts the string's length just before each delimiter. It then uses that length to extract the original string extending from the position after the delimiter. It iterates over the received encoded string until all substrings have been extracted.

This algorithm works with any valid ASCII characters as it uses the length of the string in the encoding and decoding process.

## A solution in C++

```cpp
#include <vector>
#include <string>

std::string encode(const std::vector<std::string>& strs) {
    std::string encoded_string;
    for (const auto& s : strs) {
        encoded_string += std::to_string(s.length()) + "#" + s;
    }
    return encoded_string;
}

std::vector<std::string> decode(const std::string& s) {
    std::vector<std::string> strs;
    int i = 0;
    while (i < s.length()) {
        int delimiter_pos = s.find('#', i);
        int length = std::stoi(s.substr(i, delimiter_pos - i));
        strs.push_back(s.substr(delimiter_pos + 1, length));
        i = delimiter_pos + length + 1;
    }
    return strs;
}
```
The algorithm concatenates each string with its length and a delimiter (in this case '#'). For example, ["Hello ", "World "] would be encoded into "6#Hello 6#World " (6 is the length of both "Hello " and "World ").

When decoding, the receiving side searches for the delimiter and extracts the string's length just before each delimiter. It then uses that length to extract the original string extending from the position after the delimiter. It iterates over the received encoded string until all substrings have been extracted.

This algorithm works with any valid ASCII characters as it uses the length of the string in the encoding and decoding process.

## A solution in Python

```python
def encode(strs):
    encoded_string = ""
    for s in strs:
        encoded_string += str(len(s)) + "#" + s
    return encoded_string

def decode(s):
    strs = []
    i = 0
    while i < len(s):
        delimiter_pos = s.find('#', i)
        length = int(s[i:delimiter_pos])
        strs.append(s[delimiter_pos + 1:delimiter_pos + 1 + length])
        i = delimiter_pos + 1 + length
    return strs
```
The algorithm concatenates each string with its length and a delimiter (in this case '#'). For example, ["Hello ", "World "] would be encoded into "6#Hello 6#World " (6 is the length of both "Hello " and "World ").

When decoding, the receiving side searches for the delimiter and extracts the string's length just before each delimiter. It then uses that length to extract the original string extending from the position after the delimiter. It iterates over the received encoded string until all substrings have been extracted.

This algorithm works with any valid ASCII characters as it uses the length of the string in the encoding and decoding process.

## A solution in Javascript

```javascript
function encode(strs) {
    let encodedString = "";
    for (const s of strs) {
        encodedString += s.length + "#" + s;
    }
    return encodedString;
}

function decode(s) {
    let strs = [];
    let i = 0;
    while (i < s.length) {
        const delimiterPos = s.indexOf('#', i);
        const length = parseInt(s.slice(i, delimiterPos));
        strs.push(s.slice(delimiterPos + 1, delimiterPos + 1 + length));
        i = delimiterPos + 1 + length;
    }
    return strs;
}
```
The algorithm concatenates each string with its length and a delimiter (in this case '#'). For example, ["Hello ", "World "] would be encoded into "6#Hello 6#World " (6 is the length of both "Hello " and "World ").

When decoding, the receiving side searches for the delimiter and extracts the string's length just before each delimiter. It then uses that length to extract the original string extending from the position after the delimiter. It iterates over the received encoded string until all substrings have been extracted.

This algorithm works with any valid ASCII characters as it uses the length of the string in the encoding and decoding process.


# Closest Binary Search Tree Value II

- slug: closest-binary-search-tree-value-ii
- difficulty: Hard

Given the `root` of a binary search tree, a `target` value, and an integer `k`, return _the_ `k` _values in the BST that are closest to the_ `target`. You may return the answer in **any order**.

You are **guaranteed** to have only one unique set of `k` values in the BST that are closest to the `target`.

**Example 1:**

**Input:** root = \[4,2,5,1,3\], target = 3.714286, k = 2
**Output:** \[4,3\]

**Example 2:**

**Input:** root = \[1\], target = 0.000000, k = 1
**Output:** \[1\]

**Constraints:**

*   The number of nodes in the tree is `n`.
*   `1 <= k <= n <= 104`.
*   `0 <= Node.val <= 109`
*   `-109 <= target <= 109`

**Follow up:** Assume that the BST is balanced. Could you solve it in less than `O(n)` runtime (where `n = total nodes`)?

## A solution in Java

```java
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
}

public List<Integer> closestKValues(TreeNode root, double target, int k) {
    PriorityQueue<int[]> maxHeap = new PriorityQueue<>((a, b) -> Double.compare(b[1], a[1]));
    List<Integer> values = new ArrayList<>();

    inorderTraversal(root, target, k, maxHeap);

    while (!maxHeap.isEmpty()) {
        values.add(maxHeap.poll()[0]);
    }
    return values;
}

void inorderTraversal(TreeNode node, double target, int k, PriorityQueue<int[]> maxHeap) {
    if (node == null) return;

    inorderTraversal(node.left, target, k, maxHeap);
    maxHeap.offer(new int[]{node.val, Math.abs(node.val - target)});
    if (maxHeap.size() > k) maxHeap.poll();
    inorderTraversal(node.right, target, k, maxHeap);
}
```
The proposed algorithm is an Inorder Traversal of a Binary Search Tree, which visits the nodes in ascending order. During the traversal, we calculate the absolute difference between each node's value and the target value, and maintain a max heap with the K smallest differences. In the end, we retrieve the values from the max heap and return them in the result.

The time complexity of this algorithm is O(n) due to the traversal of the whole tree. Although the follow-up question asks about a solution with less O(n) time, the provided algorithms have not considered that case.

## A solution in C++

```cpp
#include <vector>
#include <queue>
#include <cmath>
#include <cstdlib>
using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
};

vector<int> closestKValues(TreeNode* root, double target, int k) {
    vector<int> values;
    priority_queue<pair<double, int>> maxHeap;

    function<void(TreeNode*)> inorderTraverse = [&](TreeNode* node) {
        if (!node) return;
        inorderTraverse(node->left);
        maxHeap.push(make_pair(fabs(node->val - target), node->val));
        if (maxHeap.size() > k) maxHeap.pop();
        inorderTraverse(node->right);
    };

    inorderTraverse(root);
    while (!maxHeap.empty()) {
        values.push_back(maxHeap.top().second);
        maxHeap.pop();
    }
    return values;
}
```
The proposed algorithm is an Inorder Traversal of a Binary Search Tree, which visits the nodes in ascending order. During the traversal, we calculate the absolute difference between each node's value and the target value, and maintain a max heap with the K smallest differences. In the end, we retrieve the values from the max heap and return them in the result.

The time complexity of this algorithm is O(n) due to the traversal of the whole tree. Although the follow-up question asks about a solution with less O(n) time, the provided algorithms have not considered that case.

## A solution in Python

```python
from heapq import heappush, heappop

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def closestKValues(root, target, k):
    values = []
    max_heap = []

    def inorder_traverse(node):
        if not node:
            return
        inorder_traverse(node.left)
        heappush(max_heap, (-abs(node.val - target), node.val))
        if len(max_heap) > k:
            heappop(max_heap)
        inorder_traverse(node.right)

    inorder_traverse(root)
    while max_heap:
        _, val = heappop(max_heap)
        values.append(val)
    return values
```
The proposed algorithm is an Inorder Traversal of a Binary Search Tree, which visits the nodes in ascending order. During the traversal, we calculate the absolute difference between each node's value and the target value, and maintain a max heap with the K smallest differences. In the end, we retrieve the values from the max heap and return them in the result.

The time complexity of this algorithm is O(n) due to the traversal of the whole tree. Although the follow-up question asks about a solution with less O(n) time, the provided algorithms have not considered that case.

## A solution in Javascript

```javascript
class TreeNode {
    constructor(val, left=null, right=null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

function closestKValues(root, target, k) {
    const values = [];
    const maxHeap = [];

    function inorderTraversal(node) {
        if (!node) return;
        inorderTraversal(node.left);
        maxHeap.push({diff: Math.abs(node.val - target), val: node.val});
        maxHeap.sort((a, b) => b.diff - a.diff);
        if (maxHeap.length > k) maxHeap.pop();
        inorderTraversal(node.right);
    }

    inorderTraversal(root);
    for (let item of maxHeap) {
        values.push(item.val);
    }
    return values;
}
```
The proposed algorithm is an Inorder Traversal of a Binary Search Tree, which visits the nodes in ascending order. During the traversal, we calculate the absolute difference between each node's value and the target value, and maintain a max heap with the K smallest differences. In the end, we retrieve the values from the max heap and return them in the result.

The time complexity of this algorithm is O(n) due to the traversal of the whole tree. Although the follow-up question asks about a solution with less O(n) time, the provided algorithms have not considered that case.


# Integer to English Words

- slug: integer-to-english-words
- difficulty: Hard

Convert a non-negative integer `num` to its English words representation.

**Example 1:**

**Input:** num = 123
**Output:**  "One Hundred Twenty Three "

**Example 2:**

**Input:** num = 12345
**Output:**  "Twelve Thousand Three Hundred Forty Five "

**Example 3:**

**Input:** num = 1234567
**Output:**  "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven "

**Constraints:**

*   `0 <= num <= 231 - 1`

## A solution in Java

```java
import java.util.HashMap;
import java.util.Map;

public class Solution {
    private final String[] LESS_THAN_20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
    private final String[] TENS = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
    private final String[] THOUSANDS = {"", "Thousand", "Million", "Billion"};

    public String numberToWords(int num) {
        if (num == 0) return "Zero";
        StringBuilder result = new StringBuilder();
        int i = 0;
        while (num > 0) {
            if (num % 1000 != 0) {
                result.insert(0, helper(num % 1000) + THOUSANDS[i] + " ");
            }
            num /= 1000;
            i++;
        }
        return result.toString().trim();
    }

    private String helper(int num) {
        if (num == 0) {
            return "";
        } else if (num < 20) {
            return LESS_THAN_20[num] + " ";
        } else if (num < 100) {
            return TENS[num / 10] + " " + helper(num % 10);
        } else {
            return LESS_THAN_20[num / 100] + " Hundred " + helper(num % 100);
        }
    }
}
```
The algorithm uses a divide-and-conquer approach, where the given integer is broken down into smaller chunks, based on the powers of thousand (thousands, millions, and billions). By using the integer division and modulo, it determines how many times each chunk occurs in the number. Then, for each chunk, it constructs a word representation using the lookup tables for LESS_THAN_20, TENS, and THOUSANDS, and combines these words into the final string. Finally, it trims any extra spaces from the result.

This algorithm uses an iterative approach to go through each step of the powers of thousand.

## A solution in C++

```cpp
#include <string>
#include <vector>

class Solution {
public:
    std::string numberToWords(int num) {
        if (num == 0) return "Zero";
        std::string result;
        int i = 0;
        while (num > 0) {
            if (num % 1000 != 0) {
                result = helper(num % 1000) + THOUSANDS[i] + " " + result;
            }
            num /= 1000;
            i++;
        }
        return trim(result);
    }

private:
    std::vector<std::string> LESS_THAN_20 = {
        "", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"
    };
    std::vector<std::string> TENS = {
        "", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"
    };
    std::vector<std::string> THOUSANDS = {
        "", "Thousand", "Million", "Billion"
    };

    std::string helper(int num) {
        if (num == 0) {
            return "";
        } else if (num < 20) {
            return LESS_THAN_20[num] + " ";
        } else if (num < 100) {
            return TENS[num / 10] + " " + helper(num % 10);
        } else {
            return LESS_THAN_20[num / 100] + " Hundred " + helper(num % 100);
        }
    }

    std::string trim(const std::string& str) {
        return str.substr(0, str.find_last_not_of(' ') + 1);
    }
};
```
The algorithm uses a divide-and-conquer approach, where the given integer is broken down into smaller chunks, based on the powers of thousand (thousands, millions, and billions). By using the integer division and modulo, it determines how many times each chunk occurs in the number. Then, for each chunk, it constructs a word representation using the lookup tables for LESS_THAN_20, TENS, and THOUSANDS, and combines these words into the final string. Finally, it trims any extra spaces from the result.

This algorithm uses an iterative approach to go through each step of the powers of thousand.

## A solution in Python

```python
class Solution:
    def numberToWords(self, num: int) -> str:
        if num == 0:
            return "Zero"
        LESS_THAN_20 = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"]
        TENS = ["", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"]
        THOUSANDS = ["", "Thousand", "Million", "Billion"]

        def helper(num):
            if num == 0:
                return ""
            elif num < 20:
                return LESS_THAN_20[num] + " "
            elif num < 100:
                return TENS[num // 10] + " " + helper(num % 10)
            else:
                return LESS_THAN_20[num // 100] + " Hundred " + helper(num % 100)

        result = ""
        i = 0
        while num > 0:
            if num % 1000 != 0:
                result = helper(num % 1000) + THOUSANDS[i] + " " + result
            num //= 1000
            i += 1
        return result.strip()
```
The algorithm uses a divide-and-conquer approach, where the given integer is broken down into smaller chunks, based on the powers of thousand (thousands, millions, and billions). By using the integer division and modulo, it determines how many times each chunk occurs in the number. Then, for each chunk, it constructs a word representation using the lookup tables for LESS_THAN_20, TENS, and THOUSANDS, and combines these words into the final string. Finally, it trims any extra spaces from the result.

This algorithm uses an iterative approach to go through each step of the powers of thousand.

## A solution in Javascript

```javascript
class Solution {
    numberToWords(num) {
        if (num === 0) return "Zero";

        const LESS_THAN_20 = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"];
        const TENS = ["", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"];
        const THOUSANDS = ["", "Thousand", "Million", "Billion"];

        function helper(num) {
            if (num === 0) {
                return "";
            } else if (num < 20) {
                return LESS_THAN_20[num] + " ";
            } else if (num < 100) {
                return TENS[Math.floor(num / 10)] + " " + helper(num % 10);
            } else {
                return LESS_THAN_20[Math.floor(num / 100)] + " Hundred " + helper(num % 100);
            }
        }

        let result = "";
        let i = 0;
        while (num > 0) {
            if (num % 1000 !== 0) {
                result = helper(num % 1000) + THOUSANDS[i] + " " + result;
            }
            num = Math.floor(num / 1000);
            i++;
        }
        return result.trim();
    }
}
```
The algorithm uses a divide-and-conquer approach, where the given integer is broken down into smaller chunks, based on the powers of thousand (thousands, millions, and billions). By using the integer division and modulo, it determines how many times each chunk occurs in the number. Then, for each chunk, it constructs a word representation using the lookup tables for LESS_THAN_20, TENS, and THOUSANDS, and combines these words into the final string. Finally, it trims any extra spaces from the result.

This algorithm uses an iterative approach to go through each step of the powers of thousand.


# H-Index

- slug: h-index
- difficulty: Medium

Given an array of integers `citations` where `citations[i]` is the number of citations a researcher received for their `ith` paper, return _the researcher's h-index_.

According to the [definition of h-index on Wikipedia](https://en.wikipedia.org/wiki/H-index): The h-index is defined as the maximum value of `h` such that the given researcher has published at least `h` papers that have each been cited at least `h` times.

**Example 1:**

**Input:** citations = \[3,0,6,1,5\]
**Output:** 3
**Explanation:** \[3,0,6,1,5\] means the researcher has 5 papers in total and each of them had received 3, 0, 6, 1, 5 citations respectively.
Since the researcher has 3 papers with at least 3 citations each and the remaining two with no more than 3 citations each, their h-index is 3.

**Example 2:**

**Input:** citations = \[1,3,1\]
**Output:** 1

**Constraints:**

*   `n == citations.length`
*   `1 <= n <= 5000`
*   `0 <= citations[i] <= 1000`

## A solution in Java

```java
public int hIndex(int[] citations) {
    Arrays.sort(citations);
    int h = 0;
    for (int i = citations.length - 1; i >= 0; i--) {
        int rank = citations.length - i;
        if (citations[i] >= rank) {
            h = rank;
        } else {
            break;
        }
    }
    return h;
}
```
1. First, we sort the citations array in descending order.
2. Then, we iterate through the sorted array and compare each value with its index + 1 (zero-based index). If citations[i] is greater or equal to (i + 1), we update the h-index with the new value (i + 1). Otherwise, we break the loop since the maximum h-index is achieved.
3. Finally, we return the h-index.

## A solution in C++

```cpp
int hIndex(vector<int>& citations) {
    sort(citations.begin(), citations.end(), greater<int>());
    int h = 0;
    for (int i = 0; i < citations.size(); ++i) {
        if (citations[i] >= i + 1) {
            h = i + 1;
        } else {
            break;
        }
    }
    return h;
}
```
1. First, we sort the citations array in descending order.
2. Then, we iterate through the sorted array and compare each value with its index + 1 (zero-based index). If citations[i] is greater or equal to (i + 1), we update the h-index with the new value (i + 1). Otherwise, we break the loop since the maximum h-index is achieved.
3. Finally, we return the h-index.

## A solution in Python

```python
def hIndex(citations: List[int]) -> int:
    citations.sort(reverse=True)
    h = 0
    for i, citation in enumerate(citations):
        if citation >= i + 1:
            h = i + 1
        else:
            break
    return h
```
1. First, we sort the citations array in descending order.
2. Then, we iterate through the sorted array and compare each value with its index + 1 (zero-based index). If citations[i] is greater or equal to (i + 1), we update the h-index with the new value (i + 1). Otherwise, we break the loop since the maximum h-index is achieved.
3. Finally, we return the h-index.

## A solution in Javascript

```javascript
function hIndex(citations) {
    citations.sort((a, b) => b - a);
    let h = 0;
    for (let i = 0; i < citations.length; i++) {
        if (citations[i] >= i + 1) {
            h = i + 1;
        } else {
            break;
        }
    }
    return h;
}
```
1. First, we sort the citations array in descending order.
2. Then, we iterate through the sorted array and compare each value with its index + 1 (zero-based index). If citations[i] is greater or equal to (i + 1), we update the h-index with the new value (i + 1). Otherwise, we break the loop since the maximum h-index is achieved.
3. Finally, we return the h-index.


# H-Index II

- slug: h-index-ii
- difficulty: Medium

Given an array of integers `citations` where `citations[i]` is the number of citations a researcher received for their `ith` paper and `citations` is sorted in **ascending order**, return _the researcher's h-index_.

According to the [definition of h-index on Wikipedia](https://en.wikipedia.org/wiki/H-index): The h-index is defined as the maximum value of `h` such that the given researcher has published at least `h` papers that have each been cited at least `h` times.

You must write an algorithm that runs in logarithmic time.

**Example 1:**

**Input:** citations = \[0,1,3,5,6\]
**Output:** 3
**Explanation:** \[0,1,3,5,6\] means the researcher has 5 papers in total and each of them had received 0, 1, 3, 5, 6 citations respectively.
Since the researcher has 3 papers with at least 3 citations each and the remaining two with no more than 3 citations each, their h-index is 3.

**Example 2:**

**Input:** citations = \[1,2,100\]
**Output:** 2

**Constraints:**

*   `n == citations.length`
*   `1 <= n <= 105`
*   `0 <= citations[i] <= 1000`
*   `citations` is sorted in **ascending order**.

## A solution in Java

```java
public int hIndex(int[] citations) {
    int n = citations.length;
    int left = 0, right = n - 1;

    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (citations[mid] == n - mid) {
            return n - mid;
        } else if (citations[mid] < n - mid) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    return n - left;
}
```
The algorithm is based on binary search. The idea is to find the pivot index 'mid' such that there are 'mid' number of elements greater than or equal to 'mid'. Since the array is sorted, we can leverage binary search by comparing the middle element's value to the number of elements on its right side (which can be calculated as 'n - mid'). If the number of elements on the right side is equal to the value at mid, we found the h-index. Otherwise, if the number of elements on the right side is less than the value at mid, we move our search to the left half of the array. If the number of elements is greater than the value at mid, we move our search to the right half of the array. This process ensures logarithmic time complexity as we eliminate half of the array in each iteration. Once our search is complete (right becomes less than left), we return the final h-index as 'n - left'.

## A solution in C++

```cpp
int hIndex(vector<int>& citations) {
    int n = citations.size();
    int left = 0, right = n - 1;

    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (citations[mid] == n - mid) {
            return n - mid;
        } else if (citations[mid] < n - mid) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    return n - left;
}
```
The algorithm is based on binary search. The idea is to find the pivot index 'mid' such that there are 'mid' number of elements greater than or equal to 'mid'. Since the array is sorted, we can leverage binary search by comparing the middle element's value to the number of elements on its right side (which can be calculated as 'n - mid'). If the number of elements on the right side is equal to the value at mid, we found the h-index. Otherwise, if the number of elements on the right side is less than the value at mid, we move our search to the left half of the array. If the number of elements is greater than the value at mid, we move our search to the right half of the array. This process ensures logarithmic time complexity as we eliminate half of the array in each iteration. Once our search is complete (right becomes less than left), we return the final h-index as 'n - left'.

## A solution in Python

```python
def hIndex(citations: List[int]) -> int:
    n = len(citations)
    left, right = 0, n - 1

    while left <= right:
        mid = left + (right - left) // 2
        if citations[mid] == n - mid:
            return n - mid
        elif citations[mid] < n - mid:
            left = mid + 1
        else:
            right = mid - 1

    return n - left
```
The algorithm is based on binary search. The idea is to find the pivot index 'mid' such that there are 'mid' number of elements greater than or equal to 'mid'. Since the array is sorted, we can leverage binary search by comparing the middle element's value to the number of elements on its right side (which can be calculated as 'n - mid'). If the number of elements on the right side is equal to the value at mid, we found the h-index. Otherwise, if the number of elements on the right side is less than the value at mid, we move our search to the left half of the array. If the number of elements is greater than the value at mid, we move our search to the right half of the array. This process ensures logarithmic time complexity as we eliminate half of the array in each iteration. Once our search is complete (right becomes less than left), we return the final h-index as 'n - left'.

## A solution in Javascript

```javascript
function hIndex(citations) {
    const n = citations.length;
    let left = 0, right = n - 1;

    while (left <= right) {
        const mid = left + Math.floor((right - left) / 2);
        if (citations[mid] === n - mid) {
            return n - mid;
        } else if (citations[mid] < n - mid) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    return n - left;
}
```
The algorithm is based on binary search. The idea is to find the pivot index 'mid' such that there are 'mid' number of elements greater than or equal to 'mid'. Since the array is sorted, we can leverage binary search by comparing the middle element's value to the number of elements on its right side (which can be calculated as 'n - mid'). If the number of elements on the right side is equal to the value at mid, we found the h-index. Otherwise, if the number of elements on the right side is less than the value at mid, we move our search to the left half of the array. If the number of elements is greater than the value at mid, we move our search to the right half of the array. This process ensures logarithmic time complexity as we eliminate half of the array in each iteration. Once our search is complete (right becomes less than left), we return the final h-index as 'n - left'.


# Paint Fence

- slug: paint-fence
- difficulty: Medium

You are painting a fence of `n` posts with `k` different colors. You must paint the posts following these rules:

*   Every post must be painted **exactly one** color.
*   There **cannot** be three or more **consecutive** posts with the same color.

Given the two integers `n` and `k`, return _the **number of ways** you can paint the fence_.

**Example 1:**

**Input:** n = 3, k = 2
**Output:** 6
**Explanation:** All the possibilities are shown.
Note that painting all the posts red or all the posts green is invalid because there cannot be three posts in a row with the same color.

**Example 2:**

**Input:** n = 1, k = 1
**Output:** 1

**Example 3:**

**Input:** n = 7, k = 2
**Output:** 42

**Constraints:**

*   `1 <= n <= 50`
*   `1 <= k <= 105`
*   The testcases are generated such that the answer is in the range `[0, 231 - 1]` for the given `n` and `k`.

## A solution in Java

```java
public int numWays(int n, int k) {
    if (n == 0) return 0;
    if (n == 1) return k;
    int same = k;
    int different = k * (k - 1);
    for (int i = 2; i < n; ++i) {
        int temp = different;
        different = (same + different) * (k - 1);
        same = temp;
    }
    return same + different;
}
```
We start with two cases when n equals to 0 or 1.
If n equals 0, it means there are no posts, so the result will be 0.
If n equals 1, it means there is only one post and k colors to choose from, so the result will be k.

After that, we create two variables: `same` and `different`. `same` stores the number of ways to color a fence at position i, such that the color of post i is the same as that of post i-1. `different` stores the number of ways to color the post at position i, such that the color of post i is different from that of post i-1.

For the first two posts, there are k ways to paint them the same color, and k*(k-1) ways to paint them different colors.

Then we use a loop starting from the third post (i=2) to the last post (i=n-1).
At each iteration, we update `different` by adding the previous `same` and `different` values and multiply by (k-1). This is because for different colors, they can either come from previous same colors or different colors, hence the addition. And then we multiply it by (k-1) to consider all possible color combinations excluding the previous color. After that, we update `same` by the previous `different` value, because now we need to consider the current post having the same color as the previous post.

Finally, we return the total number of ways which is the sum of `same` and `different`.

## A solution in C++

```cpp
int numWays(int n, int k) {
    if (n == 0) return 0;
    if (n == 1) return k;
    int same = k;
    int different = k * (k - 1);
    for (int i = 2; i < n; ++i) {
        int temp = different;
        different = (same + different) * (k - 1);
        same = temp;
    }
    return same + different;
}
```
We start with two cases when n equals to 0 or 1.
If n equals 0, it means there are no posts, so the result will be 0.
If n equals 1, it means there is only one post and k colors to choose from, so the result will be k.

After that, we create two variables: `same` and `different`. `same` stores the number of ways to color a fence at position i, such that the color of post i is the same as that of post i-1. `different` stores the number of ways to color the post at position i, such that the color of post i is different from that of post i-1.

For the first two posts, there are k ways to paint them the same color, and k*(k-1) ways to paint them different colors.

Then we use a loop starting from the third post (i=2) to the last post (i=n-1).
At each iteration, we update `different` by adding the previous `same` and `different` values and multiply by (k-1). This is because for different colors, they can either come from previous same colors or different colors, hence the addition. And then we multiply it by (k-1) to consider all possible color combinations excluding the previous color. After that, we update `same` by the previous `different` value, because now we need to consider the current post having the same color as the previous post.

Finally, we return the total number of ways which is the sum of `same` and `different`.

## A solution in Python

```python
def numWays(n, k):
    if n == 0:
        return 0
    if n == 1:
        return k
    same = k
    different = k * (k - 1)
    for i in range(2, n):
        temp = different
        different = (same + different) * (k - 1)
        same = temp
    return same + different
```
We start with two cases when n equals to 0 or 1.
If n equals 0, it means there are no posts, so the result will be 0.
If n equals 1, it means there is only one post and k colors to choose from, so the result will be k.

After that, we create two variables: `same` and `different`. `same` stores the number of ways to color a fence at position i, such that the color of post i is the same as that of post i-1. `different` stores the number of ways to color the post at position i, such that the color of post i is different from that of post i-1.

For the first two posts, there are k ways to paint them the same color, and k*(k-1) ways to paint them different colors.

Then we use a loop starting from the third post (i=2) to the last post (i=n-1).
At each iteration, we update `different` by adding the previous `same` and `different` values and multiply by (k-1). This is because for different colors, they can either come from previous same colors or different colors, hence the addition. And then we multiply it by (k-1) to consider all possible color combinations excluding the previous color. After that, we update `same` by the previous `different` value, because now we need to consider the current post having the same color as the previous post.

Finally, we return the total number of ways which is the sum of `same` and `different`.

## A solution in Javascript

```javascript
function numWays(n, k) {
    if (n === 0) return 0;
    if (n === 1) return k;

    let same = k;
    let different = k * (k - 1);
    for (let i = 2; i < n; ++i) {
        const temp = different;
        different = (same + different) * (k - 1);
        same = temp;
    }
    return same + different;
}
```
We start with two cases when n equals to 0 or 1.
If n equals 0, it means there are no posts, so the result will be 0.
If n equals 1, it means there is only one post and k colors to choose from, so the result will be k.

After that, we create two variables: `same` and `different`. `same` stores the number of ways to color a fence at position i, such that the color of post i is the same as that of post i-1. `different` stores the number of ways to color the post at position i, such that the color of post i is different from that of post i-1.

For the first two posts, there are k ways to paint them the same color, and k*(k-1) ways to paint them different colors.

Then we use a loop starting from the third post (i=2) to the last post (i=n-1).
At each iteration, we update `different` by adding the previous `same` and `different` values and multiply by (k-1). This is because for different colors, they can either come from previous same colors or different colors, hence the addition. And then we multiply it by (k-1) to consider all possible color combinations excluding the previous color. After that, we update `same` by the previous `different` value, because now we need to consider the current post having the same color as the previous post.

Finally, we return the total number of ways which is the sum of `same` and `different`.


# Find the Celebrity

- slug: find-the-celebrity
- difficulty: Medium

Suppose you are at a party with `n` people labeled from `0` to `n - 1` and among them, there may exist one celebrity. The definition of a celebrity is that all the other `n - 1` people know the celebrity, but the celebrity does not know any of them.

Now you want to find out who the celebrity is or verify that there is not one. You are only allowed to ask questions like: "Hi, A. Do you know B? " to get information about whether A knows B. You need to find out the celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense).

You are given a helper function `bool knows(a, b)` that tells you whether `a` knows `b`. Implement a function `int findCelebrity(n)`. There will be exactly one celebrity if they are at the party.

Return _the celebrity's label if there is a celebrity at the party_. If there is no celebrity, return `-1`.

**Example 1:**

**Input:** graph = \[\[1,1,0\],\[0,1,0\],\[1,1,1\]\]
**Output:** 1
**Explanation:** There are three persons labeled with 0, 1 and 2. graph\[i\]\[j\] = 1 means person i knows person j, otherwise graph\[i\]\[j\] = 0 means person i does not know person j. The celebrity is the person labeled as 1 because both 0 and 2 know him but 1 does not know anybody.

**Example 2:**

**Input:** graph = \[\[1,0,1\],\[1,1,0\],\[0,1,1\]\]
**Output:** -1
**Explanation:** There is no celebrity.

**Constraints:**

*   `n == graph.length == graph[i].length`
*   `2 <= n <= 100`
*   `graph[i][j]` is `0` or `1`.
*   `graph[i][i] == 1`

**Follow up:** If the maximum number of allowed calls to the API `knows` is `3 * n`, could you find a solution without exceeding the maximum number of calls?

## A solution in Java

```java
public boolean knows(int a, int b);

public int findCelebrity(int n) {
    int candidate = 0;
    for (int i = 1; i < n; i++) {
        if (knows(candidate, i)) {
            candidate = i;
        }
    }

    for (int i = 0; i < n; i++) {
        if (i != candidate && (knows(candidate, i) || !knows(i, candidate))) {
            return -1;
        }
    }
    return candidate;
}
```
First, we select an initial candidate with a value of 0. We loop through the other people and check if the current candidate knows the current person. If the candidate knows this person, we change the candidate to the current person. The idea is to eliminate those who can't be celebrities because they know someone else.

After the first loop, we have the final candidate. We now loop through all people to confirm that this candidate is a celebrity by checking that the candidate does not know any other person and that all other people know the candidate.

If our candidate passes both checks for all people, we have found our celebrity and return their index. If they are not a celebrity, we return -1.

## A solution in C++

```cpp
bool knows(int a, int b);

int findCelebrity(int n) {
    int candidate = 0;
    for (int i = 1; i < n; i++) {
        if (knows(candidate, i)) {
            candidate = i;
        }
    }

    for (int i = 0; i < n; i++) {
        if (i != candidate && (knows(candidate, i) || !knows(i, candidate))) {
            return -1;
        }
    }
    return candidate;
}
```
First, we select an initial candidate with a value of 0. We loop through the other people and check if the current candidate knows the current person. If the candidate knows this person, we change the candidate to the current person. The idea is to eliminate those who can't be celebrities because they know someone else.

After the first loop, we have the final candidate. We now loop through all people to confirm that this candidate is a celebrity by checking that the candidate does not know any other person and that all other people know the candidate.

If our candidate passes both checks for all people, we have found our celebrity and return their index. If they are not a celebrity, we return -1.

## A solution in Python

```python
def knows(a: int, b:int) -> bool:
    pass

def findCelebrity(n: int) -> int:
    candidate = 0
    for i in range(1, n):
        if knows(candidate, i):
            candidate = i

    for i in range(n):
        if i != candidate and (knows(candidate, i) or not knows(i, candidate)):
            return -1
    return candidate
```
First, we select an initial candidate with a value of 0. We loop through the other people and check if the current candidate knows the current person. If the candidate knows this person, we change the candidate to the current person. The idea is to eliminate those who can't be celebrities because they know someone else.

After the first loop, we have the final candidate. We now loop through all people to confirm that this candidate is a celebrity by checking that the candidate does not know any other person and that all other people know the candidate.

If our candidate passes both checks for all people, we have found our celebrity and return their index. If they are not a celebrity, we return -1.

## A solution in Javascript

```javascript
function knows(a, b) {
    // Implementation not shown
}

function findCelebrity(n) {
    let candidate = 0;
    for (let i = 1; i < n; i++) {
        if (knows(candidate, i)) {
            candidate = i;
        }
    }

    for (let i = 0; i < n; i++) {
        if (i !== candidate && (knows(candidate, i) || !knows(i, candidate))) {
            return -1;
        }
    }
    return candidate;
}
```
First, we select an initial candidate with a value of 0. We loop through the other people and check if the current candidate knows the current person. If the candidate knows this person, we change the candidate to the current person. The idea is to eliminate those who can't be celebrities because they know someone else.

After the first loop, we have the final candidate. We now loop through all people to confirm that this candidate is a celebrity by checking that the candidate does not know any other person and that all other people know the candidate.

If our candidate passes both checks for all people, we have found our celebrity and return their index. If they are not a celebrity, we return -1.


# First Bad Version

- slug: first-bad-version
- difficulty: Easy

You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.

Suppose you have `n` versions `[1, 2, ..., n]` and you want to find out the first bad one, which causes all the following ones to be bad.

You are given an API `bool isBadVersion(version)` which returns whether `version` is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.

**Example 1:**

**Input:** n = 5, bad = 4
**Output:** 4
**Explanation:**
call isBadVersion(3) -> false
call isBadVersion(5) -> true
call isBadVersion(4) -> true
Then 4 is the first bad version.

**Example 2:**

**Input:** n = 1, bad = 1
**Output:** 1

**Constraints:**

*   `1 <= bad <= n <= 231 - 1`

## A solution in Java

```java
public int firstBadVersion(int n) {
    int left = 1;
    int right = n;
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (isBadVersion(mid)) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    return left;
}
```
The algorithm used here is a binary search approach which starts with the range from the first to the last version. In each iteration, it takes the middle point and checks if it's a bad version by calling `isBadVersion()` API.

If the middle version is bad, this means that the first bad version is either the middle version or somewhere on the left side of the range. So, we update the right end of the range to the middle version.

If the middle version is not bad, the first bad version must be somewhere on the right side of the range. So, we update the left end of the range to the middle version + 1.

The loop will continue until the left and right pointers converge, indicating that we have found the first bad version. As a result, we return the value of the left pointer.

This algorithm has a complexity of O(log n), as it reduces the search range by half at each iteration hence minimizing the number of calls to the API.

## A solution in C++

```cpp
int firstBadVersion(int n) {
    int left = 1;
    int right = n;
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (isBadVersion(mid)) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    return left;
}
```
The algorithm used here is a binary search approach which starts with the range from the first to the last version. In each iteration, it takes the middle point and checks if it's a bad version by calling `isBadVersion()` API.

If the middle version is bad, this means that the first bad version is either the middle version or somewhere on the left side of the range. So, we update the right end of the range to the middle version.

If the middle version is not bad, the first bad version must be somewhere on the right side of the range. So, we update the left end of the range to the middle version + 1.

The loop will continue until the left and right pointers converge, indicating that we have found the first bad version. As a result, we return the value of the left pointer.

This algorithm has a complexity of O(log n), as it reduces the search range by half at each iteration hence minimizing the number of calls to the API.

## A solution in Python

```python
def first_bad_version(n):
    left, right = 1, n
    while left < right:
        mid = left + (right - left) // 2
        if is_bad_version(mid):
            right = mid
        else:
            left = mid + 1
    return left
```
The algorithm used here is a binary search approach which starts with the range from the first to the last version. In each iteration, it takes the middle point and checks if it's a bad version by calling `isBadVersion()` API.

If the middle version is bad, this means that the first bad version is either the middle version or somewhere on the left side of the range. So, we update the right end of the range to the middle version.

If the middle version is not bad, the first bad version must be somewhere on the right side of the range. So, we update the left end of the range to the middle version + 1.

The loop will continue until the left and right pointers converge, indicating that we have found the first bad version. As a result, we return the value of the left pointer.

This algorithm has a complexity of O(log n), as it reduces the search range by half at each iteration hence minimizing the number of calls to the API.

## A solution in Javascript

```javascript
function firstBadVersion(n) {
    let left = 1;
    let right = n;
    while (left < right) {
        let mid = Math.floor(left + (right - left) / 2);
        if (isBadVersion(mid)) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    return left;
}
```
The algorithm used here is a binary search approach which starts with the range from the first to the last version. In each iteration, it takes the middle point and checks if it's a bad version by calling `isBadVersion()` API.

If the middle version is bad, this means that the first bad version is either the middle version or somewhere on the left side of the range. So, we update the right end of the range to the middle version.

If the middle version is not bad, the first bad version must be somewhere on the right side of the range. So, we update the left end of the range to the middle version + 1.

The loop will continue until the left and right pointers converge, indicating that we have found the first bad version. As a result, we return the value of the left pointer.

This algorithm has a complexity of O(log n), as it reduces the search range by half at each iteration hence minimizing the number of calls to the API.


# Perfect Squares

- slug: perfect-squares
- difficulty: Medium

Given an integer `n`, return _the least number of perfect square numbers that sum to_ `n`.

A **perfect square** is an integer that is the square of an integer; in other words, it is the product of some integer with itself. For example, `1`, `4`, `9`, and `16` are perfect squares while `3` and `11` are not.

**Example 1:**

**Input:** n = 12
**Output:** 3
**Explanation:** 12 = 4 + 4 + 4.

**Example 2:**

**Input:** n = 13
**Output:** 2
**Explanation:** 13 = 4 + 9.

**Constraints:**

*   `1 <= n <= 104`

## A solution in Java

```java
public int numSquares(int n) {
    int[] dp = new int[n + 1];
    Arrays.fill(dp, Integer.MAX_VALUE);
    dp[0] = 0;

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j * j <= i; j++) {
            dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
        }
    }

    return dp[n];
}
```
We use Dynamic Programming (DP) to solve this problem. We initialize a 1-dimensional DP array, `dp`, of size `n + 1`, where `n` is given in the problem statement. We set `dp[0]` to `0` because it takes zero square numbers to sum up to zero. We fill the rest of the DP array with a maximum or infinite value, depending on the language used.

We iterate through the DP array from index `1` to index `n`, inclusive. For each index `i`, we iterate through all perfect square numbers `j * j` smaller than or equal to `i` to find the least number of perfect square numbers that sum up to `i`. We update the `dp` array with the minimum value of the current value at `dp[i]` and `dp[i - j * j] + 1`.

After completing the iterations, the value at `dp[n]` represents the least number of perfect squares that sum to `n`.

## A solution in C++

```cpp
#include <vector>
#include <limits>
#include <cmath>

int numSquares(int n) {
    std::vector<int> dp(n + 1, std::numeric_limits<int>::max());
    dp[0] = 0;

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j * j <= i; j++) {
            dp[i] = std::min(dp[i], dp[i - j * j] + 1);
        }
    }

    return dp[n];
}
```
We use Dynamic Programming (DP) to solve this problem. We initialize a 1-dimensional DP array, `dp`, of size `n + 1`, where `n` is given in the problem statement. We set `dp[0]` to `0` because it takes zero square numbers to sum up to zero. We fill the rest of the DP array with a maximum or infinite value, depending on the language used.

We iterate through the DP array from index `1` to index `n`, inclusive. For each index `i`, we iterate through all perfect square numbers `j * j` smaller than or equal to `i` to find the least number of perfect square numbers that sum up to `i`. We update the `dp` array with the minimum value of the current value at `dp[i]` and `dp[i - j * j] + 1`.

After completing the iterations, the value at `dp[n]` represents the least number of perfect squares that sum to `n`.

## A solution in Python

```python
def numSquares(n):
    dp = [float('inf')] * (n + 1)
    dp[0] = 0

    for i in range(1, n + 1):
        j = 1
        while j * j <= i:
            dp[i] = min(dp[i], dp[i - j * j] + 1)
            j += 1

    return dp[n]
```
We use Dynamic Programming (DP) to solve this problem. We initialize a 1-dimensional DP array, `dp`, of size `n + 1`, where `n` is given in the problem statement. We set `dp[0]` to `0` because it takes zero square numbers to sum up to zero. We fill the rest of the DP array with a maximum or infinite value, depending on the language used.

We iterate through the DP array from index `1` to index `n`, inclusive. For each index `i`, we iterate through all perfect square numbers `j * j` smaller than or equal to `i` to find the least number of perfect square numbers that sum up to `i`. We update the `dp` array with the minimum value of the current value at `dp[i]` and `dp[i - j * j] + 1`.

After completing the iterations, the value at `dp[n]` represents the least number of perfect squares that sum to `n`.

## A solution in Javascript

```javascript
function numSquares(n) {
    const dp = new Array(n + 1).fill(Infinity);
    dp[0] = 0;

    for (let i = 1; i <= n; i++) {
        for (let j = 1; j * j <= i; j++) {
            dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
        }
    }

    return dp[n];
}
```
We use Dynamic Programming (DP) to solve this problem. We initialize a 1-dimensional DP array, `dp`, of size `n + 1`, where `n` is given in the problem statement. We set `dp[0]` to `0` because it takes zero square numbers to sum up to zero. We fill the rest of the DP array with a maximum or infinite value, depending on the language used.

We iterate through the DP array from index `1` to index `n`, inclusive. For each index `i`, we iterate through all perfect square numbers `j * j` smaller than or equal to `i` to find the least number of perfect square numbers that sum up to `i`. We update the `dp` array with the minimum value of the current value at `dp[i]` and `dp[i - j * j] + 1`.

After completing the iterations, the value at `dp[n]` represents the least number of perfect squares that sum to `n`.


# Wiggle Sort

- slug: wiggle-sort
- difficulty: Medium

Given an integer array `nums`, reorder it such that `nums[0] <= nums[1] >= nums[2] <= nums[3]...`.

You may assume the input array always has a valid answer.

**Example 1:**

**Input:** nums = \[3,5,2,1,6,4\]
**Output:** \[3,5,1,6,2,4\]
**Explanation:** \[1,6,2,5,3,4\] is also accepted.

**Example 2:**

**Input:** nums = \[6,6,5,6,3,8\]
**Output:** \[6,6,5,6,3,8\]

**Constraints:**

*   `1 <= nums.length <= 5 * 104`
*   `0 <= nums[i] <= 104`
*   It is guaranteed that there will be an answer for the given input `nums`.

**Follow up:** Could you solve the problem in `O(n)` time complexity?

## A solution in Java

```java
public void wiggleSort(int[] nums) {
    for (int i = 1; i < nums.length; i++) {
        if (i % 2 == 0 && nums[i] > nums[i-1] || i % 2 == 1 && nums[i] < nums[i-1]) {
            int temp = nums[i];
            nums[i] = nums[i-1];
            nums[i-1] = temp;
        }
    }
}
```
The algorithm iterates through the array from index 1 to the end. It checks whether the current element violates the wiggle condition. If the current index is even and the current element is greater than the previous element, or if the current index is odd and the current element is smaller than the previous element, it swaps the current and the previous element.

## A solution in C++

```cpp
void wiggleSort(vector<int>& nums) {
    for (int i = 1; i < nums.size(); i++) {
        if (i%2 == 0 && nums[i] > nums[i-1] || i%2 == 1 && nums[i] < nums[i-1]) {
            swap(nums[i], nums[i-1]);
        }
    }
}
```
The algorithm iterates through the array from index 1 to the end. It checks whether the current element violates the wiggle condition. If the current index is even and the current element is greater than the previous element, or if the current index is odd and the current element is smaller than the previous element, it swaps the current and the previous element.

## A solution in Python

```python
def wiggleSort(nums):
    for i in range(1, len(nums)):
        if (i % 2 == 0 and nums[i] > nums[i-1]) or (i % 2 == 1 and nums[i] < nums[i-1]):
            nums[i], nums[i-1] = nums[i-1], nums[i]
```
The algorithm iterates through the array from index 1 to the end. It checks whether the current element violates the wiggle condition. If the current index is even and the current element is greater than the previous element, or if the current index is odd and the current element is smaller than the previous element, it swaps the current and the previous element.

## A solution in Javascript

```javascript
function wiggleSort(nums) {
    for (let i = 1; i < nums.length; i++) {
        if (i % 2 === 0 && nums[i] > nums[i-1] || i % 2 === 1 && nums[i] < nums[i-1]) {
            [nums[i], nums[i-1]] = [nums[i-1], nums[i]];
        }
    }
}
```
The algorithm iterates through the array from index 1 to the end. It checks whether the current element violates the wiggle condition. If the current index is even and the current element is greater than the previous element, or if the current index is odd and the current element is smaller than the previous element, it swaps the current and the previous element.


# Zigzag Iterator

- slug: zigzag-iterator
- difficulty: Medium

Given two vectors of integers `v1` and `v2`, implement an iterator to return their elements alternately.

Implement the `ZigzagIterator` class:

*   `ZigzagIterator(List v1, List v2)` initializes the object with the two vectors `v1` and `v2`.
*   `boolean hasNext()` returns `true` if the iterator still has elements, and `false` otherwise.
*   `int next()` returns the current element of the iterator and moves the iterator to the next element.

**Example 1:**

**Input:** v1 = \[1,2\], v2 = \[3,4,5,6\]
**Output:** \[1,3,2,4,5,6\]
**Explanation:** By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: \[1,3,2,4,5,6\].

**Example 2:**

**Input:** v1 = \[1\], v2 = \[\]
**Output:** \[1\]

**Example 3:**

**Input:** v1 = \[\], v2 = \[1\]
**Output:** \[1\]

**Constraints:**

*   `0 <= v1.length, v2.length <= 1000`
*   `1 <= v1.length + v2.length <= 2000`
*   `-231 <= v1[i], v2[i] <= 231 - 1`

**Follow up:** What if you are given `k` vectors? How well can your code be extended to such cases?

**Clarification for the follow-up question:**

The "Zigzag " order is not clearly defined and is ambiguous for `k > 2` cases. If "Zigzag " does not look right to you, replace "Zigzag " with "Cyclic ".

**Follow-up Example:**

**Input:** v1 = \[1,2,3\], v2 = \[4,5,6,7\], v3 = \[8,9\]
**Output:** \[1,4,8,2,5,9,3,6,7\]

## A solution in Java

```java
import java.util.List;
import java.util.ArrayList;

public class ZigzagIterator {
    private List<Integer> list1;
    private List<Integer> list2;
    private boolean isList1;
    private int index1, index2;

    public ZigzagIterator(List<Integer> v1, List<Integer> v2) {
        list1 = v1;
        list2 = v2;
        isList1 = list1.size() > 0;
        index1 = 0;
        index2 = 0;
    }

    public int next() {
        if (isList1 && index1 < list1.size()) {
            isList1 = !isList1;
            return list1.get(index1++);
        } else {
            isList1 = !isList1;
            return list2.get(index2++);
        }
    }

    public boolean hasNext() {
        return index1 < list1.size() || index2 < list2.size();
    }
}
```
The ZigzagIterator class is initialized with two vectors `v1` and `v2`. The `hasNext()` method checks whether there are any remaining elements in either vector. When the `next()` method is called, decide which vector to take the element from based on the current indices comparing to the lengths of the vectors. If there're more elements in the first vector or equal number of elements in both but the current index of the first vector is less than the current index of the second vector, we take the element from the first vector. Otherwise, we take the element from the second vector. And in every step, we move the index of the chosen vector forward. We can swap the vectors every time we decide which vector to take the element from so that the implementation can work for k > 2 vectors (cyclic order).

## A solution in C++

```cpp
class ZigzagIterator {
public:
    ZigzagIterator(vector<int>& v1, vector<int>& v2): curr_v(NULL), index1(0), index2(0) {
        if (!v1.empty()) {
            curr_v = &v1;
            other_v = &v2;
        } else if (!v2.empty()) {
            curr_v = &v2;
            other_v = &v1;
        }
    }

    int next() {
        int result = (*curr_v)[index1++];
        if (index2 < other_v->size()) {
            swap(curr_v, other_v);
            swap(index1, index2);
        }
        return result;
    }

    bool hasNext() {
        return curr_v && index1 < curr_v->size();
    }

private:
    vector<int> *curr_v;
    vector<int> *other_v;
    int index1;
    int index2;
};
```
The ZigzagIterator class is initialized with two vectors `v1` and `v2`. The `hasNext()` method checks whether there are any remaining elements in either vector. When the `next()` method is called, decide which vector to take the element from based on the current indices comparing to the lengths of the vectors. If there're more elements in the first vector or equal number of elements in both but the current index of the first vector is less than the current index of the second vector, we take the element from the first vector. Otherwise, we take the element from the second vector. And in every step, we move the index of the chosen vector forward. We can swap the vectors every time we decide which vector to take the element from so that the implementation can work for k > 2 vectors (cyclic order).

## A solution in Python

```python
class ZigzagIterator:

    def __init__(self, v1: List[int], v2: List[int]):
        self.v1, self.v2 = v1, v2
        self.index1, self.index2 = 0, 0

    def next(self) -> int:
        if self.index1 < len(self.v1) and (self.index1 <= self.index2 or self.index2 == len(self.v2)):
            result = self.v1[self.index1]
            self.index1 += 1
            return result
        if self.index2 < len(self.v2) and (self.index2 < self.index1 or self.index1 == len(self.v1)):
            result = self.v2[self.index2]
            self.index2 += 1
            return result

    def hasNext(self) -> bool:
        return self.index1 < len(self.v1) or self.index2 < len(self.v2)
```
The ZigzagIterator class is initialized with two vectors `v1` and `v2`. The `hasNext()` method checks whether there are any remaining elements in either vector. When the `next()` method is called, decide which vector to take the element from based on the current indices comparing to the lengths of the vectors. If there're more elements in the first vector or equal number of elements in both but the current index of the first vector is less than the current index of the second vector, we take the element from the first vector. Otherwise, we take the element from the second vector. And in every step, we move the index of the chosen vector forward. We can swap the vectors every time we decide which vector to take the element from so that the implementation can work for k > 2 vectors (cyclic order).

## A solution in Javascript

```javascript
class ZigzagIterator {
    constructor(v1, v2) {
        this.v1 = v1;
        this.v2 = v2;
        this.index1 = 0;
        this.index2 = 0;
    }

    next() {
        if (this.index1 < this.v1.length && (this.index1 <= this.index2 || this.index2 == this.v2.length)) {
            return this.v1[this.index1++];
        }
        if (this.index2 < this.v2.length && (this.index2 < this.index1 || this.index1 == this.v1.length)) {
            return this.v2[this.index2++];
        }
    }

    hasNext() {
        return this.index1 < this.v1.length || this.index2 < this.v2.length;
    }
}
```
The ZigzagIterator class is initialized with two vectors `v1` and `v2`. The `hasNext()` method checks whether there are any remaining elements in either vector. When the `next()` method is called, decide which vector to take the element from based on the current indices comparing to the lengths of the vectors. If there're more elements in the first vector or equal number of elements in both but the current index of the first vector is less than the current index of the second vector, we take the element from the first vector. Otherwise, we take the element from the second vector. And in every step, we move the index of the chosen vector forward. We can swap the vectors every time we decide which vector to take the element from so that the implementation can work for k > 2 vectors (cyclic order).


# Expression Add Operators

- slug: expression-add-operators
- difficulty: Hard

Given a string `num` that contains only digits and an integer `target`, return _**all possibilities** to insert the binary operators_ `'+'`_,_ `'-'`_, and/or_ `'*'` _between the digits of_ `num` _so that the resultant expression evaluates to the_ `target` _value_.

Note that operands in the returned expressions **should not** contain leading zeros.

**Example 1:**

**Input:** num =  "123 ", target = 6
**Output:** \[ "1\*2\*3 ", "1+2+3 "\]
**Explanation:** Both  "1\*2\*3 " and  "1+2+3 " evaluate to 6.

**Example 2:**

**Input:** num =  "232 ", target = 8
**Output:** \[ "2\*3+2 ", "2+3\*2 "\]
**Explanation:** Both  "2\*3+2 " and  "2+3\*2 " evaluate to 8.

**Example 3:**

**Input:** num =  "3456237490 ", target = 9191
**Output:** \[\]
**Explanation:** There are no expressions that can be created from  "3456237490 " to evaluate to 9191.

**Constraints:**

*   `1 <= num.length <= 10`
*   `num` consists of only digits.
*   `-231 <= target <= 231 - 1`

## A solution in Java

```java
import java.util.ArrayList;
import java.util.List;

public List<String> addOperators(String num, int target) {
    List<String> res = new ArrayList<>();
    helper(num, target, 0, 0, 0, "", res);
    return res;
}

private void helper(String num, int target, int pos, long currVal, long prevVal, String currExpr, List<String> res) {
    if (pos == num.length()) {
        if (currVal == target) {
            res.add(currExpr);
        }
        return;
    }

    for (int i = pos; i < num.length(); ++i) {
        if (i != pos && num.charAt(pos) == '0') break;
        long val = Long.parseLong(num.substring(pos, i + 1));
        if (pos == 0) {
            helper(num, target, i + 1, val, val, currExpr + num.substring(pos, i + 1), res);
        } else {
            helper(num, target, i + 1, currVal + val, val, currExpr + "+" + num.substring(pos, i + 1), res);
            helper(num, target, i + 1, currVal - val, -val, currExpr + "-" + num.substring(pos, i + 1), res);
            helper(num, target, i + 1, currVal - prevVal + prevVal * val, prevVal * val, currExpr + "*" + num.substring(pos, i + 1), res);
        }
    }
}
```
The algorithm is based on a backtracking approach. We initialize a helper function with the initial parameters, such as the starting position, expression, and running sum. The helper function is then called recursively for each possible operator insertion. When the position reaches the end of the input string, we check if the running sum equals the target. If it does, we add the current expression to the result.

We use these parameters in the helper function:

- `pos`: The current position in the input string
- `currVal`: The current value of the expression up until this point
- `prevVal`: The value before the last operator we inserted
- `currExpr`: The expression string that we are building up

To avoid leading zeros in operands, we use a check to terminate the loop if we encounter a zero at the start.

Inside the helper function, we iterate over the possible next positions ('i') in the input string and decide which operation to perform at the current position:

1. Base case: When the current position is 0, we simply update the current value and expression with no operator.
2. Addition: We update the current value by adding the parsed value, and append "+" followed by the substring to the expression.
3. Subtraction: We update the current value by subtracting the parsed value, and append "-" followed by the substring to the expression.
4. Multiplication: We update the current value by first subtracting the previous value, then adding the product of the previous value and the parsed value, and append "*" followed by the substring to the expression.

After the helper function iterates through all possibilities, we return the result as a list of expressions that evaluate to the target value.

## A solution in C++

```cpp
#include <string>
#include <vector>

void helper(const std::string &num, int target, int pos, long long currVal, long long prevVal, std::string currExpr, std::vector<std::string> &res) {
    if (pos == num.size()) {
        if (currVal == target) {
            res.push_back(currExpr);
        }
        return;
    }

    for (int i = pos; i < num.size(); ++i) {
        if (i != pos && num[pos] == '0') break;
        long long val = std::stoll(num.substr(pos, i - pos + 1));
        if (pos == 0) {
            helper(num, target, i + 1, val, val, currExpr + num.substr(pos, i - pos + 1), res);
        } else {
            helper(num, target, i + 1, currVal + val, val, currExpr + "+" + num.substr(pos, i - pos + 1), res);
            helper(num, target, i + 1, currVal - val, -val, currExpr + "-" + num.substr(pos, i - pos + 1), res);
            helper(num, target, i + 1, currVal - prevVal + prevVal * val, prevVal * val, currExpr + "*" + num.substr(pos, i - pos + 1), res);
        }
    }
}

std::vector<std::string> addOperators(std::string num, int target) {
    std::vector<std::string> res;
    helper(num, target, 0, 0, 0, "", res);
    return res;
}
```
The algorithm is based on a backtracking approach. We initialize a helper function with the initial parameters, such as the starting position, expression, and running sum. The helper function is then called recursively for each possible operator insertion. When the position reaches the end of the input string, we check if the running sum equals the target. If it does, we add the current expression to the result.

We use these parameters in the helper function:

- `pos`: The current position in the input string
- `currVal`: The current value of the expression up until this point
- `prevVal`: The value before the last operator we inserted
- `currExpr`: The expression string that we are building up

To avoid leading zeros in operands, we use a check to terminate the loop if we encounter a zero at the start.

Inside the helper function, we iterate over the possible next positions ('i') in the input string and decide which operation to perform at the current position:

1. Base case: When the current position is 0, we simply update the current value and expression with no operator.
2. Addition: We update the current value by adding the parsed value, and append "+" followed by the substring to the expression.
3. Subtraction: We update the current value by subtracting the parsed value, and append "-" followed by the substring to the expression.
4. Multiplication: We update the current value by first subtracting the previous value, then adding the product of the previous value and the parsed value, and append "*" followed by the substring to the expression.

After the helper function iterates through all possibilities, we return the result as a list of expressions that evaluate to the target value.

## A solution in Python

```python
from typing import List

def addOperators(num: str, target: int) -> List[str]:
    def helper(num, target, pos, currVal, prevVal, currExpr):
        if pos == len(num):
            if currVal == target:
                res.append(currExpr)
            return

        for i in range(pos, len(num)):
            if i != pos and num[pos] == '0':
                break

            val = int(num[pos:i + 1])
            if pos == 0:
                helper(num, target, i + 1, val, val, currExpr + num[pos:i + 1])
            else:
                helper(num, target, i + 1, currVal + val, val, currExpr + "+" + num[pos:i + 1])
                helper(num, target, i + 1, currVal - val, -val, currExpr + "-" + num[pos:i + 1])
                helper(num, target, i + 1, currVal - prevVal + prevVal * val, prevVal * val, currExpr + "*" + num[pos:i + 1])

    res = []
    helper(num, target, 0, 0, 0, "")
    return res
```
The algorithm is based on a backtracking approach. We initialize a helper function with the initial parameters, such as the starting position, expression, and running sum. The helper function is then called recursively for each possible operator insertion. When the position reaches the end of the input string, we check if the running sum equals the target. If it does, we add the current expression to the result.

We use these parameters in the helper function:

- `pos`: The current position in the input string
- `currVal`: The current value of the expression up until this point
- `prevVal`: The value before the last operator we inserted
- `currExpr`: The expression string that we are building up

To avoid leading zeros in operands, we use a check to terminate the loop if we encounter a zero at the start.

Inside the helper function, we iterate over the possible next positions ('i') in the input string and decide which operation to perform at the current position:

1. Base case: When the current position is 0, we simply update the current value and expression with no operator.
2. Addition: We update the current value by adding the parsed value, and append "+" followed by the substring to the expression.
3. Subtraction: We update the current value by subtracting the parsed value, and append "-" followed by the substring to the expression.
4. Multiplication: We update the current value by first subtracting the previous value, then adding the product of the previous value and the parsed value, and append "*" followed by the substring to the expression.

After the helper function iterates through all possibilities, we return the result as a list of expressions that evaluate to the target value.

## A solution in Javascript

```javascript
var addOperators = function(num, target) {
    const res = [];
    const helper = (num, target, pos, currVal, prevVal, currExpr) => {
        if (pos === num.length) {
            if (currVal === target) {
                res.push(currExpr);
            }
            return;
        }

        for (let i = pos; i < num.length; ++i) {
            if (i !== pos && num[pos] === '0') break;

            const val = parseInt(num.substring(pos, i + 1));
            if (pos === 0) {
                helper(num, target, i + 1, val, val, currExpr + num.substring(pos, i + 1));
            } else {
                helper(num, target, i + 1, currVal + val, val, currExpr + "+" + num.substring(pos, i + 1));
                helper(num, target, i + 1, currVal - val, -val, currExpr + "-" + num.substring(pos, i + 1));
                helper(num, target, i + 1, currVal - prevVal + prevVal * val, prevVal * val, currExpr + "*" + num.substring(pos, i + 1));
            }
        }
    }

    helper(num, target, 0, 0, 0, "");
    return res;
}
```
The algorithm is based on a backtracking approach. We initialize a helper function with the initial parameters, such as the starting position, expression, and running sum. The helper function is then called recursively for each possible operator insertion. When the position reaches the end of the input string, we check if the running sum equals the target. If it does, we add the current expression to the result.

We use these parameters in the helper function:

- `pos`: The current position in the input string
- `currVal`: The current value of the expression up until this point
- `prevVal`: The value before the last operator we inserted
- `currExpr`: The expression string that we are building up

To avoid leading zeros in operands, we use a check to terminate the loop if we encounter a zero at the start.

Inside the helper function, we iterate over the possible next positions ('i') in the input string and decide which operation to perform at the current position:

1. Base case: When the current position is 0, we simply update the current value and expression with no operator.
2. Addition: We update the current value by adding the parsed value, and append "+" followed by the substring to the expression.
3. Subtraction: We update the current value by subtracting the parsed value, and append "-" followed by the substring to the expression.
4. Multiplication: We update the current value by first subtracting the previous value, then adding the product of the previous value and the parsed value, and append "*" followed by the substring to the expression.

After the helper function iterates through all possibilities, we return the result as a list of expressions that evaluate to the target value.


# Move Zeroes

- slug: move-zeroes
- difficulty: Easy

Given an integer array `nums`, move all `0`'s to the end of it while maintaining the relative order of the non-zero elements.

**Note** that you must do this in-place without making a copy of the array.

**Example 1:**

**Input:** nums = \[0,1,0,3,12\]
**Output:** \[1,3,12,0,0\]

**Example 2:**

**Input:** nums = \[0\]
**Output:** \[0\]

**Constraints:**

*   `1 <= nums.length <= 104`
*   `-231 <= nums[i] <= 231 - 1`

**Follow up:** Could you minimize the total number of operations done?

## A solution in Java

```java
public void moveZeroes(int[] nums) {
    int index = 0;
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] != 0) {
            nums[index++] = nums[i];
        }
    }
    for (int i = index; i < nums.length; i++) {
        nums[i] = 0;
    }
}
```
In each language, the algorithm starts by initializing an `index` variable with the value of 0. Next, it loops through the input array `nums`. If the current element is not zero, it assigns the value of the current element to the position indicated by the `index` and then increments the `index`. After the first loop, all non-zero elements are placed before the zero elements in the array.

Finally, in the second loop, it assigns the value of 0 to all remaining positions in the array from the current `index` to the end of the array.

This algorithm maintains the relative order of non-zero elements as they are moved to the left at the beginning of the array, and ensures that zeros are moved to the end of the array. The algorithm also modifies the given array in-place as required.

## A solution in C++

```cpp
void moveZeroes(vector<int>& nums) {
    int index = 0;
    for (int i = 0; i < nums.size(); i++) {
        if (nums[i] != 0) {
            nums[index++] = nums[i];
        }
    }
    for (int i = index; i < nums.size(); i++) {
        nums[i] = 0;
    }
}
```
In each language, the algorithm starts by initializing an `index` variable with the value of 0. Next, it loops through the input array `nums`. If the current element is not zero, it assigns the value of the current element to the position indicated by the `index` and then increments the `index`. After the first loop, all non-zero elements are placed before the zero elements in the array.

Finally, in the second loop, it assigns the value of 0 to all remaining positions in the array from the current `index` to the end of the array.

This algorithm maintains the relative order of non-zero elements as they are moved to the left at the beginning of the array, and ensures that zeros are moved to the end of the array. The algorithm also modifies the given array in-place as required.

## A solution in Python

```python
def moveZeroes(nums):
    index = 0
    for i in range(len(nums)):
        if nums[i] != 0:
            nums[index] = nums[i]
            index += 1
    for i in range(index, len(nums)):
        nums[i] = 0
```
In each language, the algorithm starts by initializing an `index` variable with the value of 0. Next, it loops through the input array `nums`. If the current element is not zero, it assigns the value of the current element to the position indicated by the `index` and then increments the `index`. After the first loop, all non-zero elements are placed before the zero elements in the array.

Finally, in the second loop, it assigns the value of 0 to all remaining positions in the array from the current `index` to the end of the array.

This algorithm maintains the relative order of non-zero elements as they are moved to the left at the beginning of the array, and ensures that zeros are moved to the end of the array. The algorithm also modifies the given array in-place as required.

## A solution in Javascript

```javascript
function moveZeroes(nums) {
    let index = 0;
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] !== 0) {
            nums[index++] = nums[i];
        }
    }
    for (let i = index; i < nums.length; i++) {
        nums[i] = 0;
    }
}
```
In each language, the algorithm starts by initializing an `index` variable with the value of 0. Next, it loops through the input array `nums`. If the current element is not zero, it assigns the value of the current element to the position indicated by the `index` and then increments the `index`. After the first loop, all non-zero elements are placed before the zero elements in the array.

Finally, in the second loop, it assigns the value of 0 to all remaining positions in the array from the current `index` to the end of the array.

This algorithm maintains the relative order of non-zero elements as they are moved to the left at the beginning of the array, and ensures that zeros are moved to the end of the array. The algorithm also modifies the given array in-place as required.


# Peeking Iterator

- slug: peeking-iterator
- difficulty: Medium

Design an iterator that supports the `peek` operation on an existing iterator in addition to the `hasNext` and the `next` operations.

Implement the `PeekingIterator` class:

*   `PeekingIterator(Iterator nums)` Initializes the object with the given integer iterator `iterator`.
*   `int next()` Returns the next element in the array and moves the pointer to the next element.
*   `boolean hasNext()` Returns `true` if there are still elements in the array.
*   `int peek()` Returns the next element in the array **without** moving the pointer.

**Note:** Each language may have a different implementation of the constructor and `Iterator`, but they all support the `int next()` and `boolean hasNext()` functions.

**Example 1:**

**Input**
\[ "PeekingIterator ",  "next ",  "peek ",  "next ",  "next ",  "hasNext "\]
\[\[\[1, 2, 3\]\], \[\], \[\], \[\], \[\], \[\]\]
**Output**
\[null, 1, 2, 2, 3, false\]

**Explanation**
PeekingIterator peekingIterator = new PeekingIterator(\[1, 2, 3\]); // \[**1**,2,3\]
peekingIterator.next();    // return 1, the pointer moves to the next element \[1,**2**,3\].
peekingIterator.peek();    // return 2, the pointer does not move \[1,**2**,3\].
peekingIterator.next();    // return 2, the pointer moves to the next element \[1,2,**3**\]
peekingIterator.next();    // return 3, the pointer moves to the next element \[1,2,3\]
peekingIterator.hasNext(); // return False

**Constraints:**

*   `1 <= nums.length <= 1000`
*   `1 <= nums[i] <= 1000`
*   All the calls to `next` and `peek` are valid.
*   At most `1000` calls will be made to `next`, `hasNext`, and `peek`.

**Follow up:** How would you extend your design to be generic and work with all types, not just integer?

## A solution in Java

```java
import java.util.Iterator;

class PeekingIterator implements Iterator<Integer> {
    private Iterator<Integer> iterator;
    private Integer next;

    public PeekingIterator(Iterator<Integer> iterator) {
        this.iterator = iterator;
        if (iterator.hasNext()) {
            next = iterator.next();
        }
    }

    public Integer peek() {
        return next;
    }

    @Override
    public Integer next() {
        Integer current = next;
        next = iterator.hasNext() ? iterator.next() : null;
        return current;
    }

    @Override
    public boolean hasNext() {
        return next != null;
    }
}
```
The PeekingIterator class implements an iterator that supports the peek operation in addition to the regular hasNext and next methods. The constructor takes an existing iterator or iterable object, and initializes the class variables for keeping track of the next value and the internal iterator.

The peek method returns the next value in the sequence, without advancing the internal iterator. The next method returns the next value in the sequence and advances the internal iterator by calling its next method. The hasNext method checks if there are more elements left in the sequence by checking if the internal iterator's next value is not the end.

In all these implementations:

- C++ implementation uses the STL iterator standards and a vector iterator as input
- Java implementation uses the Iterator interface and expects an iterator of any collection implementing Iterable
- Python implementation accepts any iterable object as the input.
- JavaScript implementation assumes given input iterable supports the iterator protocol

## A solution in C++

```cpp
#include <iterator>

class PeekingIterator : public std::iterator<std::input_iterator_tag, int> {
public:
    PeekingIterator(std::vector<int>::iterator it, std::vector<int>::iterator end) : iterator_(it), end_(end) {
        if (iterator_ != end_) {
            next_val_ = *iterator_;
            ++iterator_;
        }
    }

    int peek() {
        return next_val_;
    }

    int next() {
        int current_val = next_val_;
        if (iterator_ != end_) {
            next_val_ = *iterator_;
            ++iterator_;
        }
        return current_val;
    }

    bool hasNext() const {
        return iterator_ != end_;
    }

private:
    std::vector<int>::iterator iterator_;
    std::vector<int>::iterator end_;
    int next_val_;
};
```
The PeekingIterator class implements an iterator that supports the peek operation in addition to the regular hasNext and next methods. The constructor takes an existing iterator or iterable object, and initializes the class variables for keeping track of the next value and the internal iterator.

The peek method returns the next value in the sequence, without advancing the internal iterator. The next method returns the next value in the sequence and advances the internal iterator by calling its next method. The hasNext method checks if there are more elements left in the sequence by checking if the internal iterator's next value is not the end.

In all these implementations:

- C++ implementation uses the STL iterator standards and a vector iterator as input
- Java implementation uses the Iterator interface and expects an iterator of any collection implementing Iterable
- Python implementation accepts any iterable object as the input.
- JavaScript implementation assumes given input iterable supports the iterator protocol

## A solution in Python

```python
class PeekingIterator:
    def __init__(self, iterator):
        self.iterator = iterator
        self.next_val = next(self.iterator, None)

    def peek(self):
        return self.next_val

    def next(self):
        current_val = self.next_val
        self.next_val = next(self.iterator, None)
        return current_val

    def hasNext(self):
        return self.next_val is not None
```
The PeekingIterator class implements an iterator that supports the peek operation in addition to the regular hasNext and next methods. The constructor takes an existing iterator or iterable object, and initializes the class variables for keeping track of the next value and the internal iterator.

The peek method returns the next value in the sequence, without advancing the internal iterator. The next method returns the next value in the sequence and advances the internal iterator by calling its next method. The hasNext method checks if there are more elements left in the sequence by checking if the internal iterator's next value is not the end.

In all these implementations:

- C++ implementation uses the STL iterator standards and a vector iterator as input
- Java implementation uses the Iterator interface and expects an iterator of any collection implementing Iterable
- Python implementation accepts any iterable object as the input.
- JavaScript implementation assumes given input iterable supports the iterator protocol

## A solution in Javascript

```javascript
class PeekingIterator {
    constructor(iterator) {
        this.iterator = iterator[Symbol.iterator]();
        this.nextValue = this.iterator.next();
    }

    peek() {
        return this.nextValue.value;
    }

    next() {
        const currentValue = this.nextValue.value;
        this.nextValue = this.iterator.next();
        return currentValue;
    }

    hasNext() {
        return !this.nextValue.done;
    }
}
```
The PeekingIterator class implements an iterator that supports the peek operation in addition to the regular hasNext and next methods. The constructor takes an existing iterator or iterable object, and initializes the class variables for keeping track of the next value and the internal iterator.

The peek method returns the next value in the sequence, without advancing the internal iterator. The next method returns the next value in the sequence and advances the internal iterator by calling its next method. The hasNext method checks if there are more elements left in the sequence by checking if the internal iterator's next value is not the end.

In all these implementations:

- C++ implementation uses the STL iterator standards and a vector iterator as input
- Java implementation uses the Iterator interface and expects an iterator of any collection implementing Iterable
- Python implementation accepts any iterable object as the input.
- JavaScript implementation assumes given input iterable supports the iterator protocol


# Inorder Successor in BST

- slug: inorder-successor-in-bst
- difficulty: Medium

Given the `root` of a binary search tree and a node `p` in it, return _the in-order successor of that node in the BST_. If the given node has no in-order successor in the tree, return `null`.

The successor of a node `p` is the node with the smallest key greater than `p.val`.

**Example 1:**

**Input:** root = \[2,1,3\], p = 1
**Output:** 2
**Explanation:** 1's in-order successor node is 2. Note that both p and the return value is of TreeNode type.

**Example 2:**

**Input:** root = \[5,3,6,2,4,null,null,1\], p = 6
**Output:** null
**Explanation:** There is no in-order successor of the current node, so the answer is `null`.

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 104]`.
*   `-105 <= Node.val <= 105`
*   All Nodes will have unique values.

## A solution in Java

```java
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
}

public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
    TreeNode successor = null;
    while (root != null) {
        if (root.val > p.val) {
            successor = root;
            root = root.left;
        } else {
            root = root.right;
        }
    }
    return successor;
}
```
In our function, `inorderSuccessor`, the goal is to find the node with the smallest key greater than the given node `p`. We start by initializing a variable `successor` as `null`.

We then run a while loop until the `root` is `null`. Within this loop, we have two conditions - one for when the root's value is greater than the value of the given node. In this case, we update the `successor` to the current root and then move to the left subtree by updating the root to its left child. If the root's value is not greater than the value of the given node, we move to the right subtree by updating the root to its right child.

At the end of the loop, when the `root` is `null`, the `successor` variable now holds our answer - the in-order successor of the given node `p` in the BST. If no in-order successor exists, it holds `null`. We return the `successor` variable.

## A solution in C++

```cpp
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
};

TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
    TreeNode* successor = nullptr;
    while (root != nullptr) {
        if (root->val > p->val) {
            successor = root;
            root = root->left;
        } else {
            root = root->right;
        }
    }
    return successor;
}
```
In our function, `inorderSuccessor`, the goal is to find the node with the smallest key greater than the given node `p`. We start by initializing a variable `successor` as `null`.

We then run a while loop until the `root` is `null`. Within this loop, we have two conditions - one for when the root's value is greater than the value of the given node. In this case, we update the `successor` to the current root and then move to the left subtree by updating the root to its left child. If the root's value is not greater than the value of the given node, we move to the right subtree by updating the root to its right child.

At the end of the loop, when the `root` is `null`, the `successor` variable now holds our answer - the in-order successor of the given node `p` in the BST. If no in-order successor exists, it holds `null`. We return the `successor` variable.

## A solution in Python

```python
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def inorder_successor(root: TreeNode, p: TreeNode) -> TreeNode:
    successor = None
    while root:
        if root.val > p.val:
            successor = root
            root = root.left
        else:
            root = root.right
    return successor
```
In our function, `inorderSuccessor`, the goal is to find the node with the smallest key greater than the given node `p`. We start by initializing a variable `successor` as `null`.

We then run a while loop until the `root` is `null`. Within this loop, we have two conditions - one for when the root's value is greater than the value of the given node. In this case, we update the `successor` to the current root and then move to the left subtree by updating the root to its left child. If the root's value is not greater than the value of the given node, we move to the right subtree by updating the root to its right child.

At the end of the loop, when the `root` is `null`, the `successor` variable now holds our answer - the in-order successor of the given node `p` in the BST. If no in-order successor exists, it holds `null`. We return the `successor` variable.

## A solution in Javascript

```javascript
class TreeNode {
    constructor(val, left = null, right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

function inorderSuccessor(root, p) {
    let successor = null;
    while (root !== null) {
        if (root.val > p.val) {
            successor = root;
            root = root.left;
        } else {
            root = root.right;
        }
    }
    return successor;
}
```
In our function, `inorderSuccessor`, the goal is to find the node with the smallest key greater than the given node `p`. We start by initializing a variable `successor` as `null`.

We then run a while loop until the `root` is `null`. Within this loop, we have two conditions - one for when the root's value is greater than the value of the given node. In this case, we update the `successor` to the current root and then move to the left subtree by updating the root to its left child. If the root's value is not greater than the value of the given node, we move to the right subtree by updating the root to its right child.

At the end of the loop, when the `root` is `null`, the `successor` variable now holds our answer - the in-order successor of the given node `p` in the BST. If no in-order successor exists, it holds `null`. We return the `successor` variable.