# Design Browser History

- slug: design-browser-history
- difficulty: Medium

You have a **browser** of one tab where you start on the `homepage` and you can visit another `url`, get back in the history number of `steps` or move forward in the history number of `steps`.

Implement the `BrowserHistory` class:

*   `BrowserHistory(string homepage)` Initializes the object with the `homepage` of the browser.
*   `void visit(string url)` Visits `url` from the current page. It clears up all the forward history.
*   `string back(int steps)` Move `steps` back in history. If you can only return `x` steps in the history and `steps > x`, you will return only `x` steps. Return the current `url` after moving back in history **at most** `steps`.
*   `string forward(int steps)` Move `steps` forward in history. If you can only forward `x` steps in the history and `steps > x`, you will forward only `x` steps. Return the current `url` after forwarding in history **at most** `steps`.

**Example:**

**Input:**
\[ "BrowserHistory ", "visit ", "visit ", "visit ", "back ", "back ", "forward ", "visit ", "forward ", "back ", "back "\]
\[\[ "leetcode.com "\],\[ "google.com "\],\[ "facebook.com "\],\[ "youtube.com "\],\[1\],\[1\],\[1\],\[ "linkedin.com "\],\[2\],\[2\],\[7\]\]
**Output:**
\[null,null,null,null, "facebook.com ", "google.com ", "facebook.com ",null, "linkedin.com ", "google.com ", "leetcode.com "\]

**Explanation:**
BrowserHistory browserHistory = new BrowserHistory( "leetcode.com ");
browserHistory.visit( "google.com ");       // You are in  "leetcode.com ". Visit  "google.com "
browserHistory.visit( "facebook.com ");     // You are in  "google.com ". Visit  "facebook.com "
browserHistory.visit( "youtube.com ");      // You are in  "facebook.com ". Visit  "youtube.com "
browserHistory.back(1);                   // You are in  "youtube.com ", move back to  "facebook.com " return  "facebook.com "
browserHistory.back(1);                   // You are in  "facebook.com ", move back to  "google.com " return  "google.com "
browserHistory.forward(1);                // You are in  "google.com ", move forward to  "facebook.com " return  "facebook.com "
browserHistory.visit( "linkedin.com ");     // You are in  "facebook.com ". Visit  "linkedin.com "
browserHistory.forward(2);                // You are in  "linkedin.com ", you cannot move forward any steps.
browserHistory.back(2);                   // You are in  "linkedin.com ", move back two steps to  "facebook.com " then to  "google.com ". return  "google.com "
browserHistory.back(7);                   // You are in  "google.com ", you can move back only one step to  "leetcode.com ". return  "leetcode.com "

**Constraints:**

*   `1 <= homepage.length <= 20`
*   `1 <= url.length <= 20`
*   `1 <= steps <= 100`
*   `homepage` and `url` consist of '.' or lower case English letters.
*   At most `5000` calls will be made to `visit`, `back`, and `forward`.

## A solution in Java

```java
import java.util.Map;
import java.util.TreeMap;

public String sortString(String s) {
    StringBuilder result = new StringBuilder();
    Map<Character, Integer> freqMap = new TreeMap<>();

    for (char c : s.toCharArray()) {
        freqMap.put(c, freqMap.getOrDefault(c, 0) + 1);
    }

    while (!freqMap.isEmpty()) {
        for (char c : new ArrayList<>(freqMap.keySet())) {
            result.append(c);
            freqMap.put(c, freqMap.get(c) - 1);
            if (freqMap.get(c) == 0) {
                freqMap.remove(c);
            }
        }

        for (char c : new ArrayList<>(freqMap.descendingKeySet())) {
            result.append(c);
            freqMap.put(c, freqMap.get(c) - 1);
            if (freqMap.get(c) == 0) {
                freqMap.remove(c);
            }
        }
    }

    return result.toString();
}
```
1. Create an ordered frequency map of each character in the given string 's'.
2. Initialize an empty result string.
3. Loop through the frequency map until it is empty.
   - In each iteration:
     a. For each character in the frequency map, append it to the result, and decrement its frequency. If the frequency becomes 0, remove the character from the frequency map.
     b. For each character in the reversed frequency map, append it to the result and decrement its frequency. If the frequency becomes 0, remove the character from the frequency map.
4. Return the result string.

## A solution in C++

```cpp
#include <string>
#include <map>

std::string sortString(std::string s) {
    std::string result;
    std::map<char, int> freq_map;

    for (char c : s) {
        freq_map[c]++;
    }

    while (!freq_map.empty()) {
        for (auto it = freq_map.begin(); it != freq_map.end();) {
            result += it->first;
            it->second--;

            if (it->second == 0) {
                it = freq_map.erase(it);
            } else {
                ++it;
            }
        }

        for (auto it = freq_map.rbegin(); it != freq_map.rend();) {
            auto next = std::next(it).base();
            result += it->first;
            it->second--;

            if (it->second == 0) {
                freq_map.erase(next);
            }
            it = std::reverse_iterator(next);
        }
    }

    return result;
}
```
1. Create an ordered frequency map of each character in the given string 's'.
2. Initialize an empty result string.
3. Loop through the frequency map until it is empty.
   - In each iteration:
     a. For each character in the frequency map, append it to the result, and decrement its frequency. If the frequency becomes 0, remove the character from the frequency map.
     b. For each character in the reversed frequency map, append it to the result and decrement its frequency. If the frequency becomes 0, remove the character from the frequency map.
4. Return the result string.

## A solution in Python

```python
from collections import OrderedDict

def sortString(s: str) -> str:
    freq_map = OrderedDict(sorted({c: s.count(c) for c in set(s)}.items()))
    result = []

    while freq_map:
        for key in list(freq_map.keys()):
            result.append(key)
            freq_map[key] -= 1

            if freq_map[key] == 0:
                del freq_map[key]

        for key in list(reversed(freq_map.keys())):
            result.append(key)
            freq_map[key] -= 1

            if freq_map[key] == 0:
                del freq_map[key]

    return "".join(result)
```
1. Create an ordered frequency map of each character in the given string 's'.
2. Initialize an empty result string.
3. Loop through the frequency map until it is empty.
   - In each iteration:
     a. For each character in the frequency map, append it to the result, and decrement its frequency. If the frequency becomes 0, remove the character from the frequency map.
     b. For each character in the reversed frequency map, append it to the result and decrement its frequency. If the frequency becomes 0, remove the character from the frequency map.
4. Return the result string.

## A solution in Javascript

```javascript
function sortString(s) {
    const freqMap = new Map([...s]
        .sort()
        .reduce((acc, c) => {
            acc.set(c, (acc.get(c) || 0) + 1);
            return acc;
        }, new Map()));
    let result = '';

    while (freqMap.size) {
        for (const [key, val] of freqMap) {
            result += key;
            if (val - 1 === 0) {
                freqMap.delete(key);
            } else {
                freqMap.set(key, val - 1);
            }
        }

        for (const [key, val] of [...freqMap].reverse()) {
            result += key;
            if (val - 1 === 0) {
                freqMap.delete(key);
            } else {
                freqMap.set(key, val - 1);
            }
        }
    }

    return result;
}
```
1. Create an ordered frequency map of each character in the given string 's'.
2. Initialize an empty result string.
3. Loop through the frequency map until it is empty.
   - In each iteration:
     a. For each character in the frequency map, append it to the result, and decrement its frequency. If the frequency becomes 0, remove the character from the frequency map.
     b. For each character in the reversed frequency map, append it to the result and decrement its frequency. If the frequency becomes 0, remove the character from the frequency map.
4. Return the result string.


# Paint House III

- slug: paint-house-iii
- difficulty: Hard

There is a row of `m` houses in a small city, each house must be painted with one of the `n` colors (labeled from `1` to `n`), some houses that have been painted last summer should not be painted again.

A neighborhood is a maximal group of continuous houses that are painted with the same color.

*   For example: `houses = [1,2,2,3,3,2,1,1]` contains `5` neighborhoods `[{1}, {2,2}, {3,3}, {2}, {1,1}]`.

Given an array `houses`, an `m x n` matrix `cost` and an integer `target` where:

*   `houses[i]`: is the color of the house `i`, and `0` if the house is not painted yet.
*   `cost[i][j]`: is the cost of paint the house `i` with the color `j + 1`.

Return _the minimum cost of painting all the remaining houses in such a way that there are exactly_ `target` _neighborhoods_. If it is not possible, return `-1`.

**Example 1:**

**Input:** houses = \[0,0,0,0,0\], cost = \[\[1,10\],\[10,1\],\[10,1\],\[1,10\],\[5,1\]\], m = 5, n = 2, target = 3
**Output:** 9
**Explanation:** Paint houses of this way \[1,2,2,1,1\]
This array contains target = 3 neighborhoods, \[{1}, {2,2}, {1,1}\].
Cost of paint all houses (1 + 1 + 1 + 1 + 5) = 9.

**Example 2:**

**Input:** houses = \[0,2,1,2,0\], cost = \[\[1,10\],\[10,1\],\[10,1\],\[1,10\],\[5,1\]\], m = 5, n = 2, target = 3
**Output:** 11
**Explanation:** Some houses are already painted, Paint the houses of this way \[2,2,1,2,2\]
This array contains target = 3 neighborhoods, \[{2,2}, {1}, {2,2}\].
Cost of paint the first and last house (10 + 1) = 11.

**Example 3:**

**Input:** houses = \[3,1,2,3\], cost = \[\[1,1,1\],\[1,1,1\],\[1,1,1\],\[1,1,1\]\], m = 4, n = 3, target = 3
**Output:** -1
**Explanation:** Houses are already painted with a total of 4 neighborhoods \[{3},{1},{2},{3}\] different of target = 3.

**Constraints:**

*   `m == houses.length == cost.length`
*   `n == cost[i].length`
*   `1 <= m <= 100`
*   `1 <= n <= 20`
*   `1 <= target <= m`
*   `0 <= houses[i] <= n`
*   `1 <= cost[i][j] <= 104`

## A solution in Java

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

public int findTheLongestSubstring(String s) {
    Map<Integer, Integer> map = new HashMap<>();
    map.put(0, -1);
    int res = 0, n = s.length(), i, j = 0;
    for (i = 0; i < n; i++) {
        switch (s.charAt(i)) {
            case 'a': j ^= 1; break;
            case 'e': j ^= 2; break;
            case 'i': j ^= 4; break;
            case 'o': j ^= 8; break;
            case 'u': j ^= 16; break;
        }
        map.putIfAbsent(j, i);
        res = Math.max(res, i - map.get(j));
    }
    return res;
}
```
The algorithm uses XOR to find a bitmask where each vowel corresponds to a bit (1 for odd occurrences, 0 for even occurrences). It loops through the input string and does bitwise XOR with an encoded version of the current character.

Each XOR operation computes the even and odd occurrences for each vowel thus far. It records the first index of the bitmask in the position mapping. The difference between the current index and the value in the position map for the bitmask will give the length of the longest substring with even vowel occurrences. It updates the answer with the maximum substring length found.

## A solution in C++

```cpp
#include <string>
#include <unordered_map>
using namespace std;

int findTheLongestSubstring(string s) {
    unordered_map<int, int> mp;
    mp[0] = -1;
    int res = 0, n = s.length(), i, j = 0;
    for (i = 0; i < n; ++i) {
        if (s[i] == 'a') j ^= 1;
        else if (s[i] == 'e') j ^= 2;
        else if (s[i] == 'i') j ^= 4;
        else if (s[i] == 'o') j ^= 8;
        else if (s[i] == 'u') j ^= 16;
        if(!mp.count(j)) mp[j] = i;
        res = max(res, i - mp[j]);
    }
    return res;
}
```
The algorithm uses XOR to find a bitmask where each vowel corresponds to a bit (1 for odd occurrences, 0 for even occurrences). It loops through the input string and does bitwise XOR with an encoded version of the current character.

Each XOR operation computes the even and odd occurrences for each vowel thus far. It records the first index of the bitmask in the position mapping. The difference between the current index and the value in the position map for the bitmask will give the length of the longest substring with even vowel occurrences. It updates the answer with the maximum substring length found.

## A solution in Python

```python
def findTheLongestSubstring(s: str) -> int:
    pos = {-1: 0}
    ans = cur = 0
    for i, c in enumerate(s):
        cur ^= 1 << ("aeiou".find(c) + 1) >> 1
        if cur not in pos:
            pos[cur] = i + 1
        ans = max(ans, i + 1 - pos[cur])
    return ans
```
The algorithm uses XOR to find a bitmask where each vowel corresponds to a bit (1 for odd occurrences, 0 for even occurrences). It loops through the input string and does bitwise XOR with an encoded version of the current character.

Each XOR operation computes the even and odd occurrences for each vowel thus far. It records the first index of the bitmask in the position mapping. The difference between the current index and the value in the position map for the bitmask will give the length of the longest substring with even vowel occurrences. It updates the answer with the maximum substring length found.

## A solution in Javascript

```javascript
function findTheLongestSubstring(s) {
    const pos = new Map();
    pos.set(0, -1);
    let ans = 0, n = s.length, i, cur = 0;
    for (i = 0; i < n; ++i) {
        switch (s.charAt(i)) {
            case 'a': cur ^= 1; break;
            case 'e': cur ^= 2; break;
            case 'i': cur ^= 4; break;
            case 'o': cur ^= 8; break;
            case 'u': cur ^= 16; break;
        }
        if(!pos.has(cur)) pos.set(cur, i);
        ans = Math.max(ans, i - pos.get(cur));
    }
    return ans;
}
```
The algorithm uses XOR to find a bitmask where each vowel corresponds to a bit (1 for odd occurrences, 0 for even occurrences). It loops through the input string and does bitwise XOR with an encoded version of the current character.

Each XOR operation computes the even and odd occurrences for each vowel thus far. It records the first index of the bitmask in the position mapping. The difference between the current index and the value in the position map for the bitmask will give the length of the longest substring with even vowel occurrences. It updates the answer with the maximum substring length found.


# Delete N Nodes After M Nodes of a Linked List

- slug: delete-n-nodes-after-m-nodes-of-a-linked-list
- difficulty: Easy

You are given the `head` of a linked list and two integers `m` and `n`.

Traverse the linked list and remove some nodes in the following way:

*   Start with the head as the current node.
*   Keep the first `m` nodes starting with the current node.
*   Remove the next `n` nodes
*   Keep repeating steps 2 and 3 until you reach the end of the list.

Return _the head of the modified list after removing the mentioned nodes_.

**Example 1:**

**Input:** head = \[1,2,3,4,5,6,7,8,9,10,11,12,13\], m = 2, n = 3
**Output:** \[1,2,6,7,11,12\]
**Explanation:** Keep the first (m = 2) nodes starting from the head of the linked List  (1 ->2) show in black nodes.
Delete the next (n = 3) nodes (3 -> 4 -> 5) show in read nodes.
Continue with the same procedure until reaching the tail of the Linked List.
Head of the linked list after removing nodes is returned.

**Example 2:**

**Input:** head = \[1,2,3,4,5,6,7,8,9,10,11\], m = 1, n = 3
**Output:** \[1,5,9\]
**Explanation:** Head of linked list after removing nodes is returned.

**Constraints:**

*   The number of nodes in the list is in the range `[1, 104]`.
*   `1 <= Node.val <= 106`
*   `1 <= m, n <= 1000`

**Follow up:** Could you solve this problem by modifying the list in-place?

## A solution in Java

```java
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

class Solution {
    int maxLen = 0;

    public int longestZigZag(TreeNode root) {
        longestZigZagUtil(root, true);
        longestZigZagUtil(root, false);
        return maxLen;
    }

    private int longestZigZagUtil(TreeNode root, boolean left) {
        if (root == null)
            return -1;

        int leftZig = longestZigZagUtil(root.left, true);
        int rightZig = longestZigZagUtil(root.right, false);

        maxLen = Math.max(maxLen, Math.max(leftZig, rightZig) + 1);
        return left ? rightZig + 1 : leftZig + 1;
    }
}
```
The algorithm is a recursive depth-first search on the binary tree. The `longestZigZagUtil` function is called with two arguments: a tree node, and a boolean value indicating if the zigzag direction is left (`True`) or right (`False`).

For each recursive call, we calculate the zigzag lengths of the left and right child nodes by calling the utility function with `left` as `True` and `False`, respectively. We update the maximum zigzag length by comparing the current maximum length with the sum of the maximum lengths of the left and right child nodes, plus one.

The base case is when `root` is `null` (Python: `None`, Java: `null`, JavaScript: `null`), in which case we return -1 as the zigzag length.

Finally, we call the utility function for both left (`True`) and right (`False`) directions to find the maximum length and return it.

## A solution in C++

```cpp
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

int longestZigZagUtil(TreeNode* root, bool left, int& maxLen) {
    if (!root)
        return -1;

    int leftZig = longestZigZagUtil(root->left, true, maxLen);
    int rightZig = longestZigZagUtil(root->right, false, maxLen);

    maxLen = max(maxLen, max(leftZig, rightZig) + 1);
    return left ? rightZig + 1 : leftZig + 1;
}

int longestZigZag(TreeNode* root) {
    int maxLen = 0;
    longestZigZagUtil(root, true, maxLen);
    longestZigZagUtil(root, false, maxLen);
    return maxLen;
}
```
The algorithm is a recursive depth-first search on the binary tree. The `longestZigZagUtil` function is called with two arguments: a tree node, and a boolean value indicating if the zigzag direction is left (`True`) or right (`False`).

For each recursive call, we calculate the zigzag lengths of the left and right child nodes by calling the utility function with `left` as `True` and `False`, respectively. We update the maximum zigzag length by comparing the current maximum length with the sum of the maximum lengths of the left and right child nodes, plus one.

The base case is when `root` is `null` (Python: `None`, Java: `null`, JavaScript: `null`), in which case we return -1 as the zigzag length.

Finally, we call the utility function for both left (`True`) and right (`False`) directions to find the maximum length and return it.

## A solution in Python

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

def longestZigZag(root: TreeNode) -> int:
    maxLen = [0]

    def longestZigZagUtil(root, left):
        if not root:
            return -1

        leftZig = longestZigZagUtil(root.left, True)
        rightZig = longestZigZagUtil(root.right, False)

        maxLen[0] = max(maxLen[0], max(leftZig, rightZig) + 1)
        return rightZig + 1 if left else leftZig + 1

    longestZigZagUtil(root, True)
    longestZigZagUtil(root, False)
    return maxLen[0]
```
The algorithm is a recursive depth-first search on the binary tree. The `longestZigZagUtil` function is called with two arguments: a tree node, and a boolean value indicating if the zigzag direction is left (`True`) or right (`False`).

For each recursive call, we calculate the zigzag lengths of the left and right child nodes by calling the utility function with `left` as `True` and `False`, respectively. We update the maximum zigzag length by comparing the current maximum length with the sum of the maximum lengths of the left and right child nodes, plus one.

The base case is when `root` is `null` (Python: `None`, Java: `null`, JavaScript: `null`), in which case we return -1 as the zigzag length.

Finally, we call the utility function for both left (`True`) and right (`False`) directions to find the maximum length and return it.

## A solution in Javascript

```javascript
function TreeNode(val) {
    this.val = val;
    this.left = this.right = null;
}

var longestZigZag = function(root) {
    let maxLen = 0;

    const longestZigZagUtil = (root, left) => {
        if (!root)
            return -1;

        const leftZig = longestZigZagUtil(root.left, true);
        const rightZig = longestZigZagUtil(root.right, false);

        maxLen = Math.max(maxLen, Math.max(leftZig, rightZig) + 1);
        return left ? rightZig + 1 : leftZig + 1;
    }

    longestZigZagUtil(root, true);
    longestZigZagUtil(root, false);
    return maxLen;
};
```
The algorithm is a recursive depth-first search on the binary tree. The `longestZigZagUtil` function is called with two arguments: a tree node, and a boolean value indicating if the zigzag direction is left (`True`) or right (`False`).

For each recursive call, we calculate the zigzag lengths of the left and right child nodes by calling the utility function with `left` as `True` and `False`, respectively. We update the maximum zigzag length by comparing the current maximum length with the sum of the maximum lengths of the left and right child nodes, plus one.

The base case is when `root` is `null` (Python: `None`, Java: `null`, JavaScript: `null`), in which case we return -1 as the zigzag length.

Finally, we call the utility function for both left (`True`) and right (`False`) directions to find the maximum length and return it.


# Final Prices With a Special Discount in a Shop

- slug: final-prices-with-a-special-discount-in-a-shop
- difficulty: Easy

You are given an integer array `prices` where `prices[i]` is the price of the `ith` item in a shop.

There is a special discount for items in the shop. If you buy the `ith` item, then you will receive a discount equivalent to `prices[j]` where `j` is the minimum index such that `j > i` and `prices[j] <= prices[i]`. Otherwise, you will not receive any discount at all.

Return an integer array `answer` where `answer[i]` is the final price you will pay for the `ith` item of the shop, considering the special discount.

**Example 1:**

**Input:** prices = \[8,4,6,2,3\]
**Output:** \[4,2,4,2,3\]
**Explanation:**
For item 0 with price\[0\]=8 you will receive a discount equivalent to prices\[1\]=4, therefore, the final price you will pay is 8 - 4 = 4.
For item 1 with price\[1\]=4 you will receive a discount equivalent to prices\[3\]=2, therefore, the final price you will pay is 4 - 2 = 2.
For item 2 with price\[2\]=6 you will receive a discount equivalent to prices\[3\]=2, therefore, the final price you will pay is 6 - 2 = 4.
For items 3 and 4 you will not receive any discount at all.

**Example 2:**

**Input:** prices = \[1,2,3,4,5\]
**Output:** \[1,2,3,4,5\]
**Explanation:** In this case, for all items, you will not receive any discount at all.

**Example 3:**

**Input:** prices = \[10,1,1,6\]
**Output:** \[9,0,1,6\]

**Constraints:**

*   `1 <= prices.length <= 500`
*   `1 <= prices[i] <= 1000`

The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only nodes with keys greater than the node's key. Both the left and right subtrees must also be binary search trees.

## A solution in Java

```java
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public int maxSumBST(TreeNode root) {
    int[] maxSum = new int[1];
    helper(root, maxSum);
    return maxSum[0];
}

private int[] helper(TreeNode node, int[] maxSum) {
    if (node == null) {
        return new int[]{Integer.MAX_VALUE, Integer.MIN_VALUE, 0, 1};
    }

    int[] left = helper(node.left, maxSum);
    int[] right = helper(node.right, maxSum);

    if (left[3] != 0 && right[3] != 0 && node.val > left[1] && node.val < right[0]) {
        int sum = node.val + left[2] + right[2];
        maxSum[0] = Math.max(maxSum[0], sum);
        return new int[]{Math.min(node.val, left[0]), Math.max(node.val, right[1]), sum, 1};
    }

    return new int[]{0, 0, 0, 0};
}
```
We perform a post-order traversal of the tree, as we need information about both the left and right children of a node to determine if the current node's subtree is also a BST.

For every node, we recursively call the helper function for its left and right children, getting their min key, max key, sum of keys, and a boolean representing if the subtree rooted at these children is a BST or not.

We then check if the current node's subtree can be considered as a BST. If it is true, we update the maximum sum if needed using the sum of the keys in the current subtree. In any case, we return the minimum and maximum keys, the sum of the keys, and a boolean indicating if the current subtree is a BST or not.

After the post-order traversal is complete, we return the maximum sum found.

## A solution in C++

```cpp
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

int maxSumBST(TreeNode* root) {
    int max_sum = 0;
    helper(root, max_sum);
    return max_sum;
}

tuple<int, int, int, bool> helper(TreeNode* node, int& max_sum) {
    if (node == nullptr) {
        return {INT_MAX, INT_MIN, 0, true};
    }

    auto[left_min, left_max, left_sum, is_left_bst] = helper(node->left, max_sum);
    auto[right_min, right_max, right_sum, is_right_bst] = helper(node->right, max_sum);

    if (is_left_bst && is_right_bst && node->val > left_max && node->val < right_min) {
        int sum = node->val + left_sum + right_sum;
        max_sum = max(max_sum, sum);
        return {min(node->val, left_min), max(node->val, right_max), sum, true};
    }

    return {0, 0, 0, false};
}
```
We perform a post-order traversal of the tree, as we need information about both the left and right children of a node to determine if the current node's subtree is also a BST.

For every node, we recursively call the helper function for its left and right children, getting their min key, max key, sum of keys, and a boolean representing if the subtree rooted at these children is a BST or not.

We then check if the current node's subtree can be considered as a BST. If it is true, we update the maximum sum if needed using the sum of the keys in the current subtree. In any case, we return the minimum and maximum keys, the sum of the keys, and a boolean indicating if the current subtree is a BST or not.

After the post-order traversal is complete, we return the maximum sum found.

## A solution in Python

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

def maxSumBST(root):
    def helper(node):
        if not node:
            return float('inf'), float('-inf'), 0, True

        left_min, left_max, left_sum, is_left_bst = helper(node.left)
        right_min, right_max, right_sum, is_right_bst = helper(node.right)

        if is_left_bst and is_right_bst and node.val > left_max and node.val < right_min:
            sum_ = node.val + left_sum + right_sum
            max_sum[0] = max(max_sum[0], sum_)
            return min(node.val, left_min), max(node.val, right_max), sum_, True

        return 0, 0, 0, False

    max_sum = [0]
    helper(root)
    return max_sum[0]
```
We perform a post-order traversal of the tree, as we need information about both the left and right children of a node to determine if the current node's subtree is also a BST.

For every node, we recursively call the helper function for its left and right children, getting their min key, max key, sum of keys, and a boolean representing if the subtree rooted at these children is a BST or not.

We then check if the current node's subtree can be considered as a BST. If it is true, we update the maximum sum if needed using the sum of the keys in the current subtree. In any case, we return the minimum and maximum keys, the sum of the keys, and a boolean indicating if the current subtree is a BST or not.

After the post-order traversal is complete, we return the maximum sum found.

## A solution in Javascript

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

function maxSumBST(root) {
    let maxSum = [0];
    helper(root, maxSum);
    return maxSum[0];
}

function helper(node, maxSum) {
    if (!node) {
        return [Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER, 0, true];
    }

    let left = helper(node.left, maxSum);
    let right = helper(node.right, maxSum);

    if (left[3] && right[3] && node.val > left[1] && node.val < right[0]) {
        let sum = node.val + left[2] + right[2];
        maxSum[0] = Math.max(maxSum[0], sum);
        return [Math.min(node.val, left[0]), Math.max(node.val, right[1]), sum, true];
    }

    return [0, 0, 0, false];
}
```
We perform a post-order traversal of the tree, as we need information about both the left and right children of a node to determine if the current node's subtree is also a BST.

For every node, we recursively call the helper function for its left and right children, getting their min key, max key, sum of keys, and a boolean representing if the subtree rooted at these children is a BST or not.

We then check if the current node's subtree can be considered as a BST. If it is true, we update the maximum sum if needed using the sum of the keys in the current subtree. In any case, we return the minimum and maximum keys, the sum of the keys, and a boolean indicating if the current subtree is a BST or not.

After the post-order traversal is complete, we return the maximum sum found.


# Subrectangle Queries

- slug: subrectangle-queries
- difficulty: Medium

Implement the class `SubrectangleQueries` which receives a `rows x cols` rectangle as a matrix of integers in the constructor and supports two methods:

1. `updateSubrectangle(int row1, int col1, int row2, int col2, int newValue)`

*   Updates all values with `newValue` in the subrectangle whose upper left coordinate is `(row1,col1)` and bottom right coordinate is `(row2,col2)`.

2. `getValue(int row, int col)`

*   Returns the current value of the coordinate `(row,col)` from the rectangle.

**Example 1:**

**Input**
\[ "SubrectangleQueries ", "getValue ", "updateSubrectangle ", "getValue ", "getValue ", "updateSubrectangle ", "getValue ", "getValue "\]
\[\[\[\[1,2,1\],\[4,3,4\],\[3,2,1\],\[1,1,1\]\]\],\[0,2\],\[0,0,3,2,5\],\[0,2\],\[3,1\],\[3,0,3,2,10\],\[3,1\],\[0,2\]\]
**Output**
\[null,1,null,5,5,null,10,5\]
**Explanation**
SubrectangleQueries subrectangleQueries = new SubrectangleQueries(\[\[1,2,1\],\[4,3,4\],\[3,2,1\],\[1,1,1\]\]);
// The initial rectangle (4x3) looks like:
// 1 2 1
// 4 3 4
// 3 2 1
// 1 1 1
subrectangleQueries.getValue(0, 2); // return 1
subrectangleQueries.updateSubrectangle(0, 0, 3, 2, 5);
// After this update the rectangle looks like:
// 5 5 5
// 5 5 5
// 5 5 5
// 5 5 5
subrectangleQueries.getValue(0, 2); // return 5
subrectangleQueries.getValue(3, 1); // return 5
subrectangleQueries.updateSubrectangle(3, 0, 3, 2, 10);
// After this update the rectangle looks like:
// 5   5   5
// 5   5   5
// 5   5   5
// 10  10  10
subrectangleQueries.getValue(3, 1); // return 10
subrectangleQueries.getValue(0, 2); // return 5

**Example 2:**

**Input**
\[ "SubrectangleQueries ", "getValue ", "updateSubrectangle ", "getValue ", "getValue ", "updateSubrectangle ", "getValue "\]
\[\[\[\[1,1,1\],\[2,2,2\],\[3,3,3\]\]\],\[0,0\],\[0,0,2,2,100\],\[0,0\],\[2,2\],\[1,1,2,2,20\],\[2,2\]\]
**Output**
\[null,1,null,100,100,null,20\]
**Explanation**
SubrectangleQueries subrectangleQueries = new SubrectangleQueries(\[\[1,1,1\],\[2,2,2\],\[3,3,3\]\]);
subrectangleQueries.getValue(0, 0); // return 1
subrectangleQueries.updateSubrectangle(0, 0, 2, 2, 100);
subrectangleQueries.getValue(0, 0); // return 100
subrectangleQueries.getValue(2, 2); // return 100
subrectangleQueries.updateSubrectangle(1, 1, 2, 2, 20);
subrectangleQueries.getValue(2, 2); // return 20

**Constraints:**

*   There will be at most `500` operations considering both methods: `updateSubrectangle` and `getValue`.
*   `1 <= rows, cols <= 100`
*   `rows == rectangle.length`
*   `cols == rectangle[i].length`
*   `0 <= row1 <= row2 < rows`
*   `0 <= col1 <= col2 < cols`
*   `1 <= newValue, rectangle[i][j] <= 10^9`
*   `0 <= row < rows`
*   `0 <= col < cols`

## A solution in Java

```java
public int countNegatives(int[][] grid) {
    int m = grid.length, n = grid[0].length, count = 0, i = 0, j = n - 1;
    while (i < m && j >= 0) {
        if (grid[i][j] < 0) {
            count += j + 1;
            i++;
        } else {
            j--;
        }
    }
    return count;
}
```
The algorithm starts from the top-right corner of the matrix and iterates through the elements diagonally towards the bottom-left corner. At each step, if a negative number is found, we add the index (j+1) of that position to the count since all other elements in the same row to the left are also negative (because the rows are sorted in non-increasing order). Then we move down to the next row.

If a positive number (or zero) is found, no negative number can be in that column or to the right of it (because the columns are also sorted in non-increasing order), and we move to the left. The loop continues until we have covered all rows or reached the leftmost column. The count of negative numbers is returned.

## A solution in C++

```cpp
int countNegatives(vector<vector<int>>& grid) {
    int m = grid.size(), n = grid[0].size(), count = 0, i = 0, j = n - 1;
    while (i < m && j >= 0) {
        if (grid[i][j] < 0) {
            count += j + 1;
            i++;
        } else {
            j--;
        }
    }
    return count;
}
```
The algorithm starts from the top-right corner of the matrix and iterates through the elements diagonally towards the bottom-left corner. At each step, if a negative number is found, we add the index (j+1) of that position to the count since all other elements in the same row to the left are also negative (because the rows are sorted in non-increasing order). Then we move down to the next row.

If a positive number (or zero) is found, no negative number can be in that column or to the right of it (because the columns are also sorted in non-increasing order), and we move to the left. The loop continues until we have covered all rows or reached the leftmost column. The count of negative numbers is returned.

## A solution in Python

```python
def countNegatives(grid):
    m, n, count, i, j = len(grid), len(grid[0]), 0, 0, len(grid[0]) - 1
    while i < m and j >= 0:
        if grid[i][j] < 0:
            count += j + 1
            i += 1
        else:
            j -= 1
    return count
```
The algorithm starts from the top-right corner of the matrix and iterates through the elements diagonally towards the bottom-left corner. At each step, if a negative number is found, we add the index (j+1) of that position to the count since all other elements in the same row to the left are also negative (because the rows are sorted in non-increasing order). Then we move down to the next row.

If a positive number (or zero) is found, no negative number can be in that column or to the right of it (because the columns are also sorted in non-increasing order), and we move to the left. The loop continues until we have covered all rows or reached the leftmost column. The count of negative numbers is returned.

## A solution in Javascript

```javascript
function countNegatives(grid) {
    const m = grid.length, n = grid[0].length;
    let count = 0, i = 0, j = n - 1;
    while (i < m && j >= 0) {
        if (grid[i][j] < 0) {
            count += j + 1;
            i++;
        } else {
            j--;
        }
    }
    return count;
}
```
The algorithm starts from the top-right corner of the matrix and iterates through the elements diagonally towards the bottom-left corner. At each step, if a negative number is found, we add the index (j+1) of that position to the count since all other elements in the same row to the left are also negative (because the rows are sorted in non-increasing order). Then we move down to the next row.

If a positive number (or zero) is found, no negative number can be in that column or to the right of it (because the columns are also sorted in non-increasing order), and we move to the left. The loop continues until we have covered all rows or reached the leftmost column. The count of negative numbers is returned.


# Find Two Non-overlapping Sub-arrays Each With Target Sum

- slug: find-two-non-overlapping-sub-arrays-each-with-target-sum
- difficulty: Medium

You are given an array of integers `arr` and an integer `target`.

You have to find **two non-overlapping sub-arrays** of `arr` each with a sum equal `target`. There can be multiple answers so you have to find an answer where the sum of the lengths of the two sub-arrays is **minimum**.

Return _the minimum sum of the lengths_ of the two required sub-arrays, or return `-1` if you cannot find such two sub-arrays.

**Example 1:**

**Input:** arr = \[3,2,2,4,3\], target = 3
**Output:** 2
**Explanation:** Only two sub-arrays have sum = 3 (\[3\] and \[3\]). The sum of their lengths is 2.

**Example 2:**

**Input:** arr = \[7,3,4,7\], target = 7
**Output:** 2
**Explanation:** Although we have three non-overlapping sub-arrays of sum = 7 (\[7\], \[3,4\] and \[7\]), but we will choose the first and third sub-arrays as the sum of their lengths is 2.

**Example 3:**

**Input:** arr = \[4,3,2,6,2,3,4\], target = 6
**Output:** -1
**Explanation:** We have only one sub-array of sum = 6.

**Constraints:**

*   `1 <= arr.length <= 105`
*   `1 <= arr[i] <= 1000`
*   `1 <= target <= 108`

## A solution in Java

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

class ProductOfNumbers {
    private List<Integer> products;

    public ProductOfNumbers() {
        products = new ArrayList<>();
        products.add(1);
    }

    public void add(int num) {
        if (num == 0) {
            products.clear();
            products.add(1);
        } else {
            products.add(products.get(products.size() - 1) * num);
        }
    }

    public int getProduct(int k) {
        if (k >= products.size()) {
            return 0;
        } else {
            return products.get(products.size() - 1) / products.get(products.size() - k - 1);
        }
    }
}
```
The algorithm maintains a growing list or vector of the cumulative products. When a new number is added, it either clears the list and starts over if the number is 0, or it adds the product of the last element and the new number to the end of the list. When the product of the last k numbers is requested, it returns the last element of the list divided by the element at the (size - k - 1) position in the list. If the list is shorter than the requested k, it returns 0 as the product will always contain a 0 in that case. The algorithm ensures that the product of any contiguous sequence of numbers will fit into a single 32-bit integer without overflowing. The complexity is O(1) for both `add` and `getProduct` operations.

## A solution in C++

```cpp
#include <vector>
using namespace std;

class ProductOfNumbers {
public:
    vector<int> products;

    ProductOfNumbers() {
        products.push_back(1);
    }

    void add(int num) {
        if (num == 0) {
            products.clear();
            products.push_back(1);
        } else {
            products.push_back(products.back() * num);
        }
    }

    int getProduct(int k) {
        if (k >= products.size()) {
            return 0;
        } else {
            return products.back() / products[products.size() - k - 1];
        }
    }
};
```
The algorithm maintains a growing list or vector of the cumulative products. When a new number is added, it either clears the list and starts over if the number is 0, or it adds the product of the last element and the new number to the end of the list. When the product of the last k numbers is requested, it returns the last element of the list divided by the element at the (size - k - 1) position in the list. If the list is shorter than the requested k, it returns 0 as the product will always contain a 0 in that case. The algorithm ensures that the product of any contiguous sequence of numbers will fit into a single 32-bit integer without overflowing. The complexity is O(1) for both `add` and `getProduct` operations.

## A solution in Python

```python
class ProductOfNumbers:
    def __init__(self):
        self.products = [1]

    def add(self, num: int) -> None:
        if num == 0:
            self.products = [1]
        else:
            self.products.append(self.products[-1] * num)

    def getProduct(self, k: int) -> int:
        if k >= len(self.products):
            return 0
        else:
            return self.products[-1] // self.products[-k - 1]
```
The algorithm maintains a growing list or vector of the cumulative products. When a new number is added, it either clears the list and starts over if the number is 0, or it adds the product of the last element and the new number to the end of the list. When the product of the last k numbers is requested, it returns the last element of the list divided by the element at the (size - k - 1) position in the list. If the list is shorter than the requested k, it returns 0 as the product will always contain a 0 in that case. The algorithm ensures that the product of any contiguous sequence of numbers will fit into a single 32-bit integer without overflowing. The complexity is O(1) for both `add` and `getProduct` operations.

## A solution in Javascript

```javascript
class ProductOfNumbers {
    constructor() {
        this.products = [1];
    }

    add(num) {
        if (num === 0) {
            this.products = [1];
        } else {
            this.products.push(this.products[this.products.length - 1] * num);
        }
    }

    getProduct(k) {
        if (k >= this.products.length) {
            return 0;
        } else {
            return this.products[this.products.length - 1] / this.products[this.products.length - k - 1];
        }
    }
}
```
The algorithm maintains a growing list or vector of the cumulative products. When a new number is added, it either clears the list and starts over if the number is 0, or it adds the product of the last element and the new number to the end of the list. When the product of the last k numbers is requested, it returns the last element of the list divided by the element at the (size - k - 1) position in the list. If the list is shorter than the requested k, it returns 0 as the product will always contain a 0 in that case. The algorithm ensures that the product of any contiguous sequence of numbers will fit into a single 32-bit integer without overflowing. The complexity is O(1) for both `add` and `getProduct` operations.


# Allocate Mailboxes

- slug: allocate-mailboxes
- difficulty: Hard

Given the array `houses` where `houses[i]` is the location of the `ith` house along a street and an integer `k`, allocate `k` mailboxes in the street.

Return _the **minimum** total distance between each house and its nearest mailbox_.

The test cases are generated so that the answer fits in a 32-bit integer.

**Example 1:**

**Input:** houses = \[1,4,8,10,20\], k = 3
**Output:** 5
**Explanation:** Allocate mailboxes in position 3, 9 and 20.
Minimum total distance from each houses to nearest mailboxes is |3-1| + |4-3| + |9-8| + |10-9| + |20-20| = 5

**Example 2:**

**Input:** houses = \[2,3,5,12,18\], k = 2
**Output:** 9
**Explanation:** Allocate mailboxes in position 3 and 14.
Minimum total distance from each houses to nearest mailboxes is |2-3| + |3-3| + |5-3| + |12-14| + |18-14| = 9.

**Constraints:**

*   `1 <= k <= houses.length <= 100`
*   `1 <= houses[i] <= 104`
*   All the integers of `houses` are **unique**.

## A solution in Java

```java
import java.util.Arrays;

public int maxEvents(int[][] events) {
    Arrays.sort(events, (a, b) -> a[1] - b[1]);

    int count = 0;
    int lastDay = -1;

    for (int[] event : events) {
        if (event[0] > lastDay) {
            count++;
            lastDay = event[1];
        }
    }

    return count;
}
```
The idea is to sort the events by end day. After sorting, iterate through the events and use a variable `lastDay` to keep track of the last day an event was attended. If the current event's start day is greater than the `lastDay`, increment the `count` (number of attended events) and set `lastDay` as the current event's end day. This greedy approach ensures we attend the events that end early and maximize the number of total attended events.

## A solution in C++

```cpp
#include <vector>
#include <algorithm>

int maxEvents(std::vector<std::vector<int>>& events) {
    std::sort(events.begin(), events.end(), [](const std::vector<int>& a, const std::vector<int>& b) {
        return a[1] < b[1];
    });

    int count = 0;
    int lastDay = -1;

    for (const auto& event : events) {
        if (event[0] > lastDay) {
            ++count;
            lastDay = event[1];
        }
    }

    return count;
}
```
The idea is to sort the events by end day. After sorting, iterate through the events and use a variable `lastDay` to keep track of the last day an event was attended. If the current event's start day is greater than the `lastDay`, increment the `count` (number of attended events) and set `lastDay` as the current event's end day. This greedy approach ensures we attend the events that end early and maximize the number of total attended events.

## A solution in Python

```python
def max_events(events):
    events.sort(key=lambda x: x[1])

    count = 0
    last_day = -1

    for event in events:
        if event[0] > last_day:
            count += 1
            last_day = event[1]

    return count
```
The idea is to sort the events by end day. After sorting, iterate through the events and use a variable `lastDay` to keep track of the last day an event was attended. If the current event's start day is greater than the `lastDay`, increment the `count` (number of attended events) and set `lastDay` as the current event's end day. This greedy approach ensures we attend the events that end early and maximize the number of total attended events.

## A solution in Javascript

```javascript
function maxEvents(events) {
    events.sort((a, b) => a[1] - b[1]);

    let count = 0;
    let lastDay = -1;

    for (const event of events) {
        if (event[0] > lastDay) {
            count++;
            lastDay = event[1];
        }
    }

    return count;
}
```
The idea is to sort the events by end day. After sorting, iterate through the events and use a variable `lastDay` to keep track of the last day an event was attended. If the current event's start day is greater than the `lastDay`, increment the `count` (number of attended events) and set `lastDay` as the current event's end day. This greedy approach ensures we attend the events that end early and maximize the number of total attended events.


# Running Sum of 1d Array

- slug: running-sum-of-1d-array
- difficulty: Easy

Given an array `nums`. We define a running sum of an array as `runningSum[i] = sum(nums[0]...nums[i])`.

Return the running sum of `nums`.

**Example 1:**

**Input:** nums = \[1,2,3,4\]
**Output:** \[1,3,6,10\]
**Explanation:** Running sum is obtained as follows: \[1, 1+2, 1+2+3, 1+2+3+4\].

**Example 2:**

**Input:** nums = \[1,1,1,1,1\]
**Output:** \[1,2,3,4,5\]
**Explanation:** Running sum is obtained as follows: \[1, 1+1, 1+1+1, 1+1+1+1, 1+1+1+1+1\].

**Example 3:**

**Input:** nums = \[3,1,2,10,1\]
**Output:** \[3,4,6,16,17\]

**Constraints:**

*   `1 <= nums.length <= 1000`
*   `-10^6 <= nums[i] <= 10^6`

## A solution in Java

```java
public int[] runningSum(int[] nums) {
    for(int i = 1; i < nums.length; i++) {
        nums[i] += nums[i - 1];
    }
    return nums;
}
```
The solution for this problem is to iterate through the input array `nums` starting from the second element (index 1). In each iteration, we add the preceding element to the current element using the formula `nums[i] += nums[i - 1]`. After finishing the loop, the modified input array is the running sum of the original array.

The logic is exactly the same across all languages; we just have to appropriately manage syntax differences.

## A solution in C++

```cpp
#include <vector>
std::vector<int> runningSum(std::vector<int>& nums) {
    for(int i = 1; i < nums.size(); i++) {
        nums[i] += nums[i - 1];
    }
    return nums;
}
```
The solution for this problem is to iterate through the input array `nums` starting from the second element (index 1). In each iteration, we add the preceding element to the current element using the formula `nums[i] += nums[i - 1]`. After finishing the loop, the modified input array is the running sum of the original array.

The logic is exactly the same across all languages; we just have to appropriately manage syntax differences.

## A solution in Python

```python
def runningSum(nums):
    for i in range(1, len(nums)):
        nums[i] += nums[i - 1]
    return nums
```
The solution for this problem is to iterate through the input array `nums` starting from the second element (index 1). In each iteration, we add the preceding element to the current element using the formula `nums[i] += nums[i - 1]`. After finishing the loop, the modified input array is the running sum of the original array.

The logic is exactly the same across all languages; we just have to appropriately manage syntax differences.

## A solution in Javascript

```javascript
function runningSum(nums) {
    for(let i = 1; i < nums.length; i++) {
        nums[i] += nums[i - 1];
    }
    return nums;
}
```
The solution for this problem is to iterate through the input array `nums` starting from the second element (index 1). In each iteration, we add the preceding element to the current element using the formula `nums[i] += nums[i - 1]`. After finishing the loop, the modified input array is the running sum of the original array.

The logic is exactly the same across all languages; we just have to appropriately manage syntax differences.


# Least Number of Unique Integers after K Removals

- slug: least-number-of-unique-integers-after-k-removals
- difficulty: Medium

Given an array of integers `arr` and an integer `k`. Find the _least number of unique integers_ after removing **exactly** `k` elements**.**

**Example 1:**

**Input:** arr = \[5,5,4\], k = 1
**Output:** 1
**Explanation**: Remove the single 4, only 5 is left.

**Example 2:**

**Input:** arr = \[4,3,1,1,3,3,2\], k = 3
**Output:** 2
**Explanation**: Remove 4, 2 and either one of the two 1s or three 3s. 1 and 3 will be left.

**Constraints:**

*   `1 <= arr.length <= 10^5`
*   `1 <= arr[i] <= 10^9`
*   `0 <= k <= arr.length`

## A solution in Java

```java
import java.util.*;
class Solution {
    public int findLeastNumOfUniqueInts(int[] arr, int k) {
        Map<Integer, Integer> count = new HashMap<>();
        for (int n : arr) {
           count.put(n, count.getOrDefault(n, 0) + 1);
        }
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        for (int freq : count.values()) {
            pq.add(freq);
        }
        while (k > 0) {
            k -= pq.poll();
        }
        return k == 0 ? pq.size() : pq.size() + 1;
    }
}
```
The algorithm first counts the frequency of each unique integer in the array using a hashmap/dictionary. Then the frequencies are put into a min-heap/priority queue. The algorithm then removes k elements, taking into consideration the least frequent integers first (popping from the min-heap). After k elements are removed, the size of the priority queue is the number of remaining unique integers. If k is exactly 0, return the size of the priority queue, otherwise, return the size + 1 (as the last integer's frequency was not completely removed from the queue).

## A solution in C++

```cpp
#include <unordered_map>
#include <queue>
int findLeastNumOfUniqueInts(vector<int>& arr, int k) {
    unordered_map<int, int> count;
    for (int n : arr) {
        count[n]++;
    }
    priority_queue<int, vector<int>, greater<int>> pq;
    for (auto &p : count) {
        pq.push(p.second);
    }
    while (k > 0) {
        k -= pq.top();
        pq.pop();
    }
    return k == 0 ? pq.size() : pq.size() + 1;
}
```
The algorithm first counts the frequency of each unique integer in the array using a hashmap/dictionary. Then the frequencies are put into a min-heap/priority queue. The algorithm then removes k elements, taking into consideration the least frequent integers first (popping from the min-heap). After k elements are removed, the size of the priority queue is the number of remaining unique integers. If k is exactly 0, return the size of the priority queue, otherwise, return the size + 1 (as the last integer's frequency was not completely removed from the queue).

## A solution in Python

```python
from collections import Counter
import heapq

def findLeastNumOfUniqueInts(arr, k):
    count = Counter(arr)
    pq = list(count.values())
    heapq.heapify(pq)
    while k > 0:
        k -= heapq.heappop(pq)
    return len(pq) if k == 0 else len(pq) + 1
```
The algorithm first counts the frequency of each unique integer in the array using a hashmap/dictionary. Then the frequencies are put into a min-heap/priority queue. The algorithm then removes k elements, taking into consideration the least frequent integers first (popping from the min-heap). After k elements are removed, the size of the priority queue is the number of remaining unique integers. If k is exactly 0, return the size of the priority queue, otherwise, return the size + 1 (as the last integer's frequency was not completely removed from the queue).

## A solution in Javascript

```javascript
function findLeastNumOfUniqueInts(arr, k) {
    let count = {};
    for (let n of arr) {
        count[n] = (count[n] || 0) + 1;
    }
    let pq = Object.values(count).sort((a, b) => a - b);
    while (k > 0) {
        k -= pq.shift();
    }
    return k === 0 ? pq.length : pq.length + 1;
}
```
The algorithm first counts the frequency of each unique integer in the array using a hashmap/dictionary. Then the frequencies are put into a min-heap/priority queue. The algorithm then removes k elements, taking into consideration the least frequent integers first (popping from the min-heap). After k elements are removed, the size of the priority queue is the number of remaining unique integers. If k is exactly 0, return the size of the priority queue, otherwise, return the size + 1 (as the last integer's frequency was not completely removed from the queue).


# Minimum Number of Days to Make m Bouquets

- slug: minimum-number-of-days-to-make-m-bouquets
- difficulty: Medium

You are given an integer array `bloomDay`, an integer `m` and an integer `k`.

You want to make `m` bouquets. To make a bouquet, you need to use `k` **adjacent flowers** from the garden.

The garden consists of `n` flowers, the `ith` flower will bloom in the `bloomDay[i]` and then can be used in **exactly one** bouquet.

Return _the minimum number of days you need to wait to be able to make_ `m` _bouquets from the garden_. If it is impossible to make m bouquets return `-1`.

**Example 1:**

**Input:** bloomDay = \[1,10,3,10,2\], m = 3, k = 1
**Output:** 3
**Explanation:** Let us see what happened in the first three days. x means flower bloomed and \_ means flower did not bloom in the garden.
We need 3 bouquets each should contain 1 flower.
After day 1: \[x, \_, \_, \_, \_\]   // we can only make one bouquet.
After day 2: \[x, \_, \_, \_, x\]   // we can only make two bouquets.
After day 3: \[x, \_, x, \_, x\]   // we can make 3 bouquets. The answer is 3.

**Example 2:**

**Input:** bloomDay = \[1,10,3,10,2\], m = 3, k = 2
**Output:** -1
**Explanation:** We need 3 bouquets each has 2 flowers, that means we need 6 flowers. We only have 5 flowers so it is impossible to get the needed bouquets and we return -1.

**Example 3:**

**Input:** bloomDay = \[7,7,7,7,12,7,7\], m = 2, k = 3
**Output:** 12
**Explanation:** We need 2 bouquets each should have 3 flowers.
Here is the garden after the 7 and 12 days:
After day 7: \[x, x, x, x, \_, x, x\]
We can make one bouquet of the first three flowers that bloomed. We cannot make another bouquet from the last three flowers that bloomed because they are not adjacent.
After day 12: \[x, x, x, x, x, x, x\]
It is obvious that we can make two bouquets in different ways.

**Constraints:**

*   `bloomDay.length == n`
*   `1 <= n <= 105`
*   `1 <= bloomDay[i] <= 109`
*   `1 <= m <= 106`
*   `1 <= k <= n`

## A solution in Java

```java
public int[] smallerNumbersThanCurrent(int[] nums) {
    int[] result = new int[nums.length];
    for (int i = 0; i < nums.length; i++) {
        for (int j = 0; j < nums.length; j++) {
            if (nums[j] < nums[i]) {
                result[i]++;
            }
        }
    }
    return result;
}
```
The algorithm iterates through each number in the input array (nums) using a nested loop. For each number (nums[i]), it checks if another number (nums[j]) in the array is smaller than it (nums[j] < nums[i]) and increments the count if it is. The count of smaller numbers for each nums[i] is stored in the result array, which is returned at the end.

## A solution in C++

```cpp
#include <vector>
using namespace std;

vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
    vector<int> result(nums.size(), 0);
    for (int i = 0; i < nums.size(); ++i) {
        for (int j = 0; j < nums.size(); ++j) {
            if (nums[j] < nums[i]) {
                ++result[i];
            }
        }
    }
    return result;
}
```
The algorithm iterates through each number in the input array (nums) using a nested loop. For each number (nums[i]), it checks if another number (nums[j]) in the array is smaller than it (nums[j] < nums[i]) and increments the count if it is. The count of smaller numbers for each nums[i] is stored in the result array, which is returned at the end.

## A solution in Python

```python
def smallerNumbersThanCurrent(nums):
    result = [0] * len(nums)
    for i in range(len(nums)):
        for j in range(len(nums)):
            if nums[j] < nums[i]:
                result[i] += 1
    return result
```
The algorithm iterates through each number in the input array (nums) using a nested loop. For each number (nums[i]), it checks if another number (nums[j]) in the array is smaller than it (nums[j] < nums[i]) and increments the count if it is. The count of smaller numbers for each nums[i] is stored in the result array, which is returned at the end.

## A solution in Javascript

```javascript
function smallerNumbersThanCurrent(nums) {
    const result = new Array(nums.length).fill(0);
    for (let i = 0; i < nums.length; i++) {
        for (let j = 0; j < nums.length; j++) {
            if (nums[j] < nums[i]) {
                result[i]++;
            }
        }
    }
    return result;
}
```
The algorithm iterates through each number in the input array (nums) using a nested loop. For each number (nums[i]), it checks if another number (nums[j]) in the array is smaller than it (nums[j] < nums[i]) and increments the count if it is. The count of smaller numbers for each nums[i] is stored in the result array, which is returned at the end.


# Kth Ancestor of a Tree Node

- slug: kth-ancestor-of-a-tree-node
- difficulty: Hard

You are given a tree with `n` nodes numbered from `0` to `n - 1` in the form of a parent array `parent` where `parent[i]` is the parent of `ith` node. The root of the tree is node `0`. Find the `kth` ancestor of a given node.

The `kth` ancestor of a tree node is the `kth` node in the path from that node to the root node.

Implement the `TreeAncestor` class:

*   `TreeAncestor(int n, int[] parent)` Initializes the object with the number of nodes in the tree and the parent array.
*   `int getKthAncestor(int node, int k)` return the `kth` ancestor of the given node `node`. If there is no such ancestor, return `-1`.

**Example 1:**

**Input**
\[ "TreeAncestor ",  "getKthAncestor ",  "getKthAncestor ",  "getKthAncestor "\]
\[\[7, \[-1, 0, 0, 1, 1, 2, 2\]\], \[3, 1\], \[5, 2\], \[6, 3\]\]
**Output**
\[null, 1, 0, -1\]

**Explanation**
TreeAncestor treeAncestor = new TreeAncestor(7, \[-1, 0, 0, 1, 1, 2, 2\]);
treeAncestor.getKthAncestor(3, 1); // returns 1 which is the parent of 3
treeAncestor.getKthAncestor(5, 2); // returns 0 which is the grandparent of 5
treeAncestor.getKthAncestor(6, 3); // returns -1 because there is no such ancestor

**Constraints:**

*   `1 <= k <= n <= 5 * 104`
*   `parent.length == n`
*   `parent[0] == -1`
*   `0 <= parent[i] < n` for all `0 < i < n`
*   `0 <= node < n`
*   There will be at most `5 * 104` queries.

## A solution in Java

```java
import java.util.Arrays;
import java.util.Comparator;

public class Solution {
    public String rankTeams(String[] votes) {
        int teams = votes[0].length();
        int[][] ranks = new int[26][teams];

        for (String vote : votes) {
            for (int i = 0; i < teams; ++i) {
                ranks[vote.charAt(i) - 'A'][i]++;
            }
        }

        Character[] result = new Character[teams];
        for (int i = 0; i < teams; ++i) {
            result[i] = votes[0].charAt(i);
        }

        Arrays.sort(result, new Comparator<Character>() {
            public int compare(Character a, Character b) {
                for (int i = 0; i < teams; ++i) {
                    if (ranks[a - 'A'][i] != ranks[b - 'A'][i]) {
                        return ranks[b - 'A'][i] - ranks[a - 'A'][i];
                    }
                }
                return a.compareTo(b);
            }
        });

        StringBuilder sb = new StringBuilder();
        for (Character ch : result) {
            sb.append(ch);
        }
        return sb.toString();
    }
}
```
1. Count the rank positions of each team in a 2D array (index 0-25 represent the team letter). The array stores the votes count for each position.
2. Sort the given team letters in lexicographical order, so it can be later used for the stable sort.
3. For each position and its votes count, sort the teams based on the number of votes they received in descending order. If two or more teams tie, use the next position's votes count, and so on. If they tie after considering all positions, sort them based on their team letter.
4. Convert the sorted team letters back into a string.

## A solution in C++

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

std::string rankTeams(std::vector<std::string>& votes) {
    int teams = votes[0].size();
    std::vector<std::vector<int>> ranks(26, std::vector<int>(teams, 0));

    for (const std::string& vote : votes) {
        for (int i = 0; i < teams; ++i) {
            ranks[vote[i] - 'A'][i]++;
        }
    }

    std::string result = votes[0];
    std::sort(result.begin(), result.end(), [&](char a, char b) {
        for (int i = 0; i < teams; ++i) {
            if (ranks[a - 'A'][i] != ranks[b - 'A'][i]) {
                return ranks[a - 'A'][i] > ranks[b - 'A'][i];
            }
        }
        return a < b;
    });

    return result;
}
```
1. Count the rank positions of each team in a 2D array (index 0-25 represent the team letter). The array stores the votes count for each position.
2. Sort the given team letters in lexicographical order, so it can be later used for the stable sort.
3. For each position and its votes count, sort the teams based on the number of votes they received in descending order. If two or more teams tie, use the next position's votes count, and so on. If they tie after considering all positions, sort them based on their team letter.
4. Convert the sorted team letters back into a string.

## A solution in Python

```python
def rank_teams(votes):
    teams = len(votes[0])
    ranks = [[0] * teams for _ in range(26)]

    for vote in votes:
        for i in range(teams):
            ranks[ord(vote[i]) - ord('A')][i] += 1

    result = list(votes[0])
    result.sort(key=lambda ch: tuple([-ranks[ord(ch) - ord('A')][i] for i in range(teams)] + [ch]))
    return ''.join(result)
```
1. Count the rank positions of each team in a 2D array (index 0-25 represent the team letter). The array stores the votes count for each position.
2. Sort the given team letters in lexicographical order, so it can be later used for the stable sort.
3. For each position and its votes count, sort the teams based on the number of votes they received in descending order. If two or more teams tie, use the next position's votes count, and so on. If they tie after considering all positions, sort them based on their team letter.
4. Convert the sorted team letters back into a string.

## A solution in Javascript

```javascript
function rankTeams(votes) {
    const teams = votes[0].length;
    const ranks = Array.from({ length: 26 }, () => Array(teams).fill(0));

    for (const vote of votes) {
        for (let i = 0; i < teams; ++i) {
            ranks[vote.charCodeAt(i) - "A".charCodeAt(0)][i]++;
        }
    }

    const result = [...votes[0]];
    result.sort((a, b) => {
        for (let i = 0; i < teams; ++i) {
            if (ranks[a.charCodeAt(0) - "A".charCodeAt(0)][i] !== ranks[b.charCodeAt(0) - "A".charCodeAt(0)][i]) {
                return ranks[b.charCodeAt(0) - "A".charCodeAt(0)][i] - ranks[a.charCodeAt(0) - "A".charCodeAt(0)][i];
            }
        }
        return a.localeCompare(b);
    });

    return result.join("");
}
```
1. Count the rank positions of each team in a 2D array (index 0-25 represent the team letter). The array stores the votes count for each position.
2. Sort the given team letters in lexicographical order, so it can be later used for the stable sort.
3. For each position and its votes count, sort the teams based on the number of votes they received in descending order. If two or more teams tie, use the next position's votes count, and so on. If they tie after considering all positions, sort them based on their team letter.
4. Convert the sorted team letters back into a string.


# Clone Binary Tree With Random Pointer

- slug: clone-binary-tree-with-random-pointer
- difficulty: Medium

A binary tree is given such that each node contains an additional random pointer which could point to any node in the tree or null.

Return a [**deep copy**](https://en.wikipedia.org/wiki/Object_copying#Deep_copy) of the tree.

The tree is represented in the same input/output way as normal binary trees where each node is represented as a pair of `[val, random_index]` where:

*   `val`: an integer representing `Node.val`
*   `random_index`: the index of the node (in the input) where the random pointer points to, or `null` if it does not point to any node.

You will be given the tree in class `Node` and you should return the cloned tree in class `NodeCopy`. `NodeCopy` class is just a clone of `Node` class with the same attributes and constructors.

**Example 1:**

**Input:** root = \[\[1,null\],null,\[4,3\],\[7,0\]\]
**Output:** \[\[1,null\],null,\[4,3\],\[7,0\]\]
**Explanation:** The original binary tree is \[1,null,4,7\].
The random pointer of node one is null, so it is represented as \[1, null\].
The random pointer of node 4 is node 7, so it is represented as \[4, 3\] where 3 is the index of node 7 in the array representing the tree.
The random pointer of node 7 is node 1, so it is represented as \[7, 0\] where 0 is the index of node 1 in the array representing the tree.

**Example 2:**

**Input:** root = \[\[1,4\],null,\[1,0\],null,\[1,5\],\[1,5\]\]
**Output:** \[\[1,4\],null,\[1,0\],null,\[1,5\],\[1,5\]\]
**Explanation:** The random pointer of a node can be the node itself.

**Example 3:**

**Input:** root = \[\[1,6\],\[2,5\],\[3,4\],\[4,3\],\[5,2\],\[6,1\],\[7,0\]\]
**Output:** \[\[1,6\],\[2,5\],\[3,4\],\[4,3\],\[5,2\],\[6,1\],\[7,0\]\]

**Constraints:**

*   The number of nodes in the `tree` is in the range `[0, 1000].`
*   `1 <= Node.val <= 106`

## A solution in Java

```java
import java.util.Queue;
import java.util.LinkedList;

public int minCost(int[][] grid) {
    int m = grid.length, n = grid[0].length;
    int[][] cost = new int[m][n];
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            cost[i][j] = 1_000_000;
        }
    }
    Queue<int[]> q = new LinkedList<>();
    dfs(grid, cost, q, 0, 0, 0);
    int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

    while (!q.isEmpty()) {
        int[] pos = q.poll();
        int r = pos[0], c = pos[1];
        for (int i = 0; i < 4; i++) {
            int nr = r + directions[i][0], nc = c + directions[i][1];
            dfs(grid, cost, q, nr, nc, cost[r][c] + (grid[r][c] == i + 1 ? 0 : 1));
        }
    }

    return cost[m - 1][n - 1];
}

void dfs(int[][] grid, int[][] cost, Queue<int[]> q, int r, int c, int d) {
    int m = grid.length, n = grid[0].length;
    if (r >= 0 && r < m && c >= 0 && c < n && d < cost[r][c]) {
        cost[r][c] = d;
        q.add(new int[]{r, c});
    }
}
```
The algorithm is to use a Depth-First Search on the grid, only updating the cost when it finds a lower-cost path. The search starts at (0, 0) and follows the directions in the grid while prioritizing modifying the signs as little as possible.

The cost of each cell in the grid is initially set to a large value. A queue is used to iteratively apply the DFS procedure. A cell is checked if it is within the boundaries of the grid and if the distance to it is less than the currently stored cost, then update the cost of the cell and push the cell coordinates onto the queue.

For each dequeued cell, iterate over all four directions, calculate the new cell coordinates according to the direction, check if the grid value matches the current direction (+1 because 1-indexed). If it does not match, increase the cost by 1. Call the DFS procedure with the new cell's row, column, and the cost.

Once the DFS procedure has been applied to all cells, the minimum cost of reaching the bottom-right cell is stored in `cost[m - 1][n - 1]`.

## A solution in C++

```cpp
#include <vector>
#include <queue>

int minCost(std::vector<std::vector<int>>& grid) {
    int m = grid.size();
    int n = grid[0].size();
    std::vector<std::vector<int>> cost(m, std::vector<int>(n, 1e6));
    std::queue<std::pair<int, int>> q;

    auto dfs = [&](int r, int c, int d) {
        if (r >= 0 && c >= 0 && r < m && c < n && (d < cost[r][c])) {
            cost[r][c] = d;
            q.push({r, c});
        }
    };

    dfs(0, 0, 0);
    const std::vector<std::pair<int, int>> directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

    while (!q.empty()) {
        int r = q.front().first;
        int c = q.front().second;
        q.pop();
        for (int i = 0; i < 4; ++i) {
            int nr = r + directions[i].first;
            int nc = c + directions[i].second;
            dfs(nr, nc, cost[r][c] + (grid[r][c] != i + 1));
        }
    }
    return cost.back().back();
}
```
The algorithm is to use a Depth-First Search on the grid, only updating the cost when it finds a lower-cost path. The search starts at (0, 0) and follows the directions in the grid while prioritizing modifying the signs as little as possible.

The cost of each cell in the grid is initially set to a large value. A queue is used to iteratively apply the DFS procedure. A cell is checked if it is within the boundaries of the grid and if the distance to it is less than the currently stored cost, then update the cost of the cell and push the cell coordinates onto the queue.

For each dequeued cell, iterate over all four directions, calculate the new cell coordinates according to the direction, check if the grid value matches the current direction (+1 because 1-indexed). If it does not match, increase the cost by 1. Call the DFS procedure with the new cell's row, column, and the cost.

Once the DFS procedure has been applied to all cells, the minimum cost of reaching the bottom-right cell is stored in `cost[m - 1][n - 1]`.

## A solution in Python

```python
from collections import deque

def minCost(grid):
    def dfs(r, c, d):
        if 0 <= r < m and 0 <= c < n and d < cost[r][c]:
            cost[r][c] = d
            q.append((r, c))

    m, n = len(grid), len(grid[0])
    cost = [[1e6] * n for _ in range(m)]

    q = deque()
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]

    dfs(0, 0, 0)

    while q:
        r, c = q.popleft()
        for i, (dr, dc) in enumerate(directions):
            dfs(r + dr, c + dc, cost[r][c] + (grid[r][c] != i + 1))

    return cost[-1][-1]
```
The algorithm is to use a Depth-First Search on the grid, only updating the cost when it finds a lower-cost path. The search starts at (0, 0) and follows the directions in the grid while prioritizing modifying the signs as little as possible.

The cost of each cell in the grid is initially set to a large value. A queue is used to iteratively apply the DFS procedure. A cell is checked if it is within the boundaries of the grid and if the distance to it is less than the currently stored cost, then update the cost of the cell and push the cell coordinates onto the queue.

For each dequeued cell, iterate over all four directions, calculate the new cell coordinates according to the direction, check if the grid value matches the current direction (+1 because 1-indexed). If it does not match, increase the cost by 1. Call the DFS procedure with the new cell's row, column, and the cost.

Once the DFS procedure has been applied to all cells, the minimum cost of reaching the bottom-right cell is stored in `cost[m - 1][n - 1]`.

## A solution in Javascript

```javascript
function minCost(grid) {
    function dfs(r, c, d) {
        if (r >= 0 && c >= 0 && r < m && c < n && d < cost[r][c]) {
            cost[r][c] = d;
            q.push([r, c]);
        }
    }

    const m = grid.length;
    const n = grid[0].length;
    const cost = Array.from({length: m}, () => new Array(n).fill(1e6));
    const q = [];
    const directions = [[0, 1], [0, -1], [1, 0], [-1, 0]];

    dfs(0, 0, 0);

    while (q.length) {
        const [r, c] = q.shift();
        for (let i = 0; i < 4; i++) {
            const nr = r + directions[i][0];
            const nc = c + directions[i][1];
            dfs(nr, nc, cost[r][c] + (grid[r][c] !== i + 1));
        }
    }

    return cost[m - 1][n - 1];
}
```
The algorithm is to use a Depth-First Search on the grid, only updating the cost when it finds a lower-cost path. The search starts at (0, 0) and follows the directions in the grid while prioritizing modifying the signs as little as possible.

The cost of each cell in the grid is initially set to a large value. A queue is used to iteratively apply the DFS procedure. A cell is checked if it is within the boundaries of the grid and if the distance to it is less than the currently stored cost, then update the cost of the cell and push the cell coordinates onto the queue.

For each dequeued cell, iterate over all four directions, calculate the new cell coordinates according to the direction, check if the grid value matches the current direction (+1 because 1-indexed). If it does not match, increase the cost by 1. Call the DFS procedure with the new cell's row, column, and the cost.

Once the DFS procedure has been applied to all cells, the minimum cost of reaching the bottom-right cell is stored in `cost[m - 1][n - 1]`.


# XOR Operation in an Array

- slug: xor-operation-in-an-array
- difficulty: Easy

You are given an integer `n` and an integer `start`.

Define an array `nums` where `nums[i] = start + 2 * i` (**0-indexed**) and `n == nums.length`.

Return _the bitwise XOR of all elements of_ `nums`.

**Example 1:**

**Input:** n = 5, start = 0
**Output:** 8
**Explanation:** Array nums is equal to \[0, 2, 4, 6, 8\] where (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8.
Where  "^ " corresponds to bitwise XOR operator.

**Example 2:**

**Input:** n = 4, start = 3
**Output:** 8
**Explanation:** Array nums is equal to \[3, 5, 7, 9\] where (3 ^ 5 ^ 7 ^ 9) = 8.

**Constraints:**

*   `1 <= n <= 1000`
*   `0 <= start <= 1000`
*   `n == nums.length`

## A solution in Java

```java
public int findTheDistanceValue(int[] arr1, int[] arr2, int d) {
    int count = 0;
    for (int i = 0; i < arr1.length; i++) {
        boolean valid = true;
        for (int j = 0; j < arr2.length; j++) {
            if (Math.abs(arr1[i] - arr2[j]) <= d) {
                valid = false;
                break;
            }
        }
        if (valid) count++;
    }
    return count;
}
```
The algorithm starts by initializing a variable `count` to store the number of elements obeying the given constraints. For every element `arr1[i]`, iterate through every element `arr2[j]`. Check if `|arr1[i] - arr2[j]| <= d`. If this condition is true, the current element `arr1[i]` is not valid, so set `valid` to false and break out of the inner loop. If the entire inner loop is exhausted and all elements `arr2[j]` did not meet this condition, the current `arr1[i]` is valid and increments the count. Return the count at the end.

## A solution in C++

```cpp
int findTheDistanceValue(vector<int>& arr1, vector<int>& arr2, int d) {
    int count = 0;
    for (int i = 0; i < arr1.size(); i++) {
        bool valid = true;
        for (int j = 0; j < arr2.size(); j++) {
            if (abs(arr1[i] - arr2[j]) <= d) {
                valid = false;
                break;
            }
        }
        if (valid) count++;
    }
    return count;
}
```
The algorithm starts by initializing a variable `count` to store the number of elements obeying the given constraints. For every element `arr1[i]`, iterate through every element `arr2[j]`. Check if `|arr1[i] - arr2[j]| <= d`. If this condition is true, the current element `arr1[i]` is not valid, so set `valid` to false and break out of the inner loop. If the entire inner loop is exhausted and all elements `arr2[j]` did not meet this condition, the current `arr1[i]` is valid and increments the count. Return the count at the end.

## A solution in Python

```python
def findTheDistanceValue(arr1, arr2, d):
    count = 0
    for i in arr1:
        valid = True
        for j in arr2:
            if abs(i - j) <= d:
                valid = False
                break
        if valid:
            count += 1
    return count
```
The algorithm starts by initializing a variable `count` to store the number of elements obeying the given constraints. For every element `arr1[i]`, iterate through every element `arr2[j]`. Check if `|arr1[i] - arr2[j]| <= d`. If this condition is true, the current element `arr1[i]` is not valid, so set `valid` to false and break out of the inner loop. If the entire inner loop is exhausted and all elements `arr2[j]` did not meet this condition, the current `arr1[i]` is valid and increments the count. Return the count at the end.

## A solution in Javascript

```javascript
function findTheDistanceValue(arr1, arr2, d) {
    let count = 0;
    for (let i = 0; i < arr1.length; i++) {
        let valid = true;
        for (let j = 0; j < arr2.length; j++) {
            if (Math.abs(arr1[i] - arr2[j]) <= d) {
                valid = false;
                break;
            }
        }
        if (valid) count++;
    }
    return count;
}
```
The algorithm starts by initializing a variable `count` to store the number of elements obeying the given constraints. For every element `arr1[i]`, iterate through every element `arr2[j]`. Check if `|arr1[i] - arr2[j]| <= d`. If this condition is true, the current element `arr1[i]` is not valid, so set `valid` to false and break out of the inner loop. If the entire inner loop is exhausted and all elements `arr2[j]` did not meet this condition, the current `arr1[i]` is valid and increments the count. Return the count at the end.


# Making File Names Unique

- slug: making-file-names-unique
- difficulty: Medium

Given an array of strings `names` of size `n`. You will create `n` folders in your file system **such that**, at the `ith` minute, you will create a folder with the name `names[i]`.

Since two files **cannot** have the same name, if you enter a folder name that was previously used, the system will have a suffix addition to its name in the form of `(k)`, where, `k` is the **smallest positive integer** such that the obtained name remains unique.

Return _an array of strings of length_ `n` where `ans[i]` is the actual name the system will assign to the `ith` folder when you create it.

**Example 1:**

**Input:** names = \[ "pes ", "fifa ", "gta ", "pes(2019) "\]
**Output:** \[ "pes ", "fifa ", "gta ", "pes(2019) "\]
**Explanation:** Let's see how the file system creates folder names:
 "pes " --> not assigned before, remains  "pes "
 "fifa " --> not assigned before, remains  "fifa "
 "gta " --> not assigned before, remains  "gta "
 "pes(2019) " --> not assigned before, remains  "pes(2019) "

**Example 2:**

**Input:** names = \[ "gta ", "gta(1) ", "gta ", "avalon "\]
**Output:** \[ "gta ", "gta(1) ", "gta(2) ", "avalon "\]
**Explanation:** Let's see how the file system creates folder names:
 "gta " --> not assigned before, remains  "gta "
 "gta(1) " --> not assigned before, remains  "gta(1) "
 "gta " --> the name is reserved, system adds (k), since  "gta(1) " is also reserved, systems put k = 2. it becomes  "gta(2) "
 "avalon " --> not assigned before, remains  "avalon "

**Example 3:**

**Input:** names = \[ "onepiece ", "onepiece(1) ", "onepiece(2) ", "onepiece(3) ", "onepiece "\]
**Output:** \[ "onepiece ", "onepiece(1) ", "onepiece(2) ", "onepiece(3) ", "onepiece(4) "\]
**Explanation:** When the last folder is created, the smallest positive valid k is 4, and it becomes  "onepiece(4) ".

**Constraints:**

*   `1 <= names.length <= 5 * 104`
*   `1 <= names[i].length <= 20`
*   `names[i]` consists of lowercase English letters, digits, and/or round brackets.

## A solution in Java

```java
import java.util.*;

public int maxNumberOfFamilies(int n, int[][] reservedSeats) {
    Map<Integer, Integer> rows = new HashMap<>();
    for (int[] seat : reservedSeats) {
        rows.put(seat[0], rows.getOrDefault(seat[0], 0) | (1 << (seat[1] - 1)));
    }

    int max_groups = (n - rows.size()) * 2;
    for (int rowMasks : rows.values()) {
        int seats = ~(rowMasks | (rowMasks >> 1) | (rowMasks >> 2) | (rowMasks >> 3)) & 0x3FF;
        max_groups += (seats & (seats >> 1) & (seats >> 2) & (seats >> 3)) != 0 ? 1 : 0;
    }

    return max_groups;
}
```
The algorithm uses bitwise operations to keep track of reserved and unreserved seats. It maintains a map (or dictionary in Python) to store the row number as the key and a bitmask representing the reserved seats as the value. For each reserved seat, it calculates the corresponding bitmask and updates the row's bitmask using bitwise OR operation.

Next, it calculates the maximum number of 4-person groups that can be formed in completely unreserved rows. This is equal to twice the number of unreserved rows (since two 4-person groups can be formed in each row). It initializes max_groups with this value.

It then iterates through each reserved row and its bitmask. To find available spots for a group, it calculates a bitmask of unreserved groups of seats each 4 contiguous empty seats. It does this using bitwise AND and NOT operations. Finally, it checks if there are any such groups in the row and increments the max_groups if there are.

At the end of the algorithm, max_groups store the maximum number of 4-person groups that can be seated.

## A solution in C++

```cpp
#include <vector>
#include <unordered_map>

int maxNumberOfFamilies(int n, std::vector<std::vector<int>>& reservedSeats) {
    std::unordered_map<int, int> rows;
    for (const auto& seat : reservedSeats) {
        rows[seat[0]] |= 1 << (seat[1] - 1);
    }

    int max_groups = (n - rows.size()) * 2;
    for (const auto& row : rows) {
        int seats = ~(row.second | (row.second >> 1) | (row.second >> 2) | (row.second >> 3)) & 0x3FF;
        max_groups += (seats & (seats >> 1) & (seats >> 2) & (seats >> 3)) != 0;
    }

    return max_groups;
}
```
The algorithm uses bitwise operations to keep track of reserved and unreserved seats. It maintains a map (or dictionary in Python) to store the row number as the key and a bitmask representing the reserved seats as the value. For each reserved seat, it calculates the corresponding bitmask and updates the row's bitmask using bitwise OR operation.

Next, it calculates the maximum number of 4-person groups that can be formed in completely unreserved rows. This is equal to twice the number of unreserved rows (since two 4-person groups can be formed in each row). It initializes max_groups with this value.

It then iterates through each reserved row and its bitmask. To find available spots for a group, it calculates a bitmask of unreserved groups of seats each 4 contiguous empty seats. It does this using bitwise AND and NOT operations. Finally, it checks if there are any such groups in the row and increments the max_groups if there are.

At the end of the algorithm, max_groups store the maximum number of 4-person groups that can be seated.

## A solution in Python

```python
def maxNumberOfFamilies(n, reservedSeats):
    rows = {}
    for seat in reservedSeats:
        rows[seat[0]] = rows.get(seat[0], 0) | (1 << (seat[1] - 1))

    max_groups = (n - len(rows)) * 2
    for row_mask in rows.values():
        seats = ~(row_mask | (row_mask >> 1) | (row_mask >> 2) | (row_mask >> 3)) & 0x3FF
        max_groups += (seats & (seats >> 1) & (seats >> 2) & (seats >> 3)) != 0

    return max_groups
```
The algorithm uses bitwise operations to keep track of reserved and unreserved seats. It maintains a map (or dictionary in Python) to store the row number as the key and a bitmask representing the reserved seats as the value. For each reserved seat, it calculates the corresponding bitmask and updates the row's bitmask using bitwise OR operation.

Next, it calculates the maximum number of 4-person groups that can be formed in completely unreserved rows. This is equal to twice the number of unreserved rows (since two 4-person groups can be formed in each row). It initializes max_groups with this value.

It then iterates through each reserved row and its bitmask. To find available spots for a group, it calculates a bitmask of unreserved groups of seats each 4 contiguous empty seats. It does this using bitwise AND and NOT operations. Finally, it checks if there are any such groups in the row and increments the max_groups if there are.

At the end of the algorithm, max_groups store the maximum number of 4-person groups that can be seated.

## A solution in Javascript

```javascript
function maxNumberOfFamilies(n, reservedSeats) {
    const rows = {};
    for (const seat of reservedSeats) {
        rows[seat[0]] = (rows[seat[0]] || 0) | (1 << (seat[1] - 1));
    }

    let max_groups = (n - Object.keys(rows).length) * 2;
    for (const row in rows) {
        const rowMasks = rows[row];
        const seats = ~(rowMasks | (rowMasks >> 1) | (rowMasks >> 2) | (rowMasks >> 3)) & 0x3FF;
        max_groups += (seats & (seats >> 1) & (seats >> 2) & (seats >> 3)) !== 0 ? 1 : 0;
    }

    return max_groups;
}
```
The algorithm uses bitwise operations to keep track of reserved and unreserved seats. It maintains a map (or dictionary in Python) to store the row number as the key and a bitmask representing the reserved seats as the value. For each reserved seat, it calculates the corresponding bitmask and updates the row's bitmask using bitwise OR operation.

Next, it calculates the maximum number of 4-person groups that can be formed in completely unreserved rows. This is equal to twice the number of unreserved rows (since two 4-person groups can be formed in each row). It initializes max_groups with this value.

It then iterates through each reserved row and its bitmask. To find available spots for a group, it calculates a bitmask of unreserved groups of seats each 4 contiguous empty seats. It does this using bitwise AND and NOT operations. Finally, it checks if there are any such groups in the row and increments the max_groups if there are.

At the end of the algorithm, max_groups store the maximum number of 4-person groups that can be seated.


# Avoid Flood in The City

- slug: avoid-flood-in-the-city
- difficulty: Medium

Your country has an infinite number of lakes. Initially, all the lakes are empty, but when it rains over the `nth` lake, the `nth` lake becomes full of water. If it rains over a lake that is **full of water**, there will be a **flood**. Your goal is to avoid floods in any lake.

Given an integer array `rains` where:

*   `rains[i] > 0` means there will be rains over the `rains[i]` lake.
*   `rains[i] == 0` means there are no rains this day and you can choose **one lake** this day and **dry it**.

Return _an array `ans`_ where:

*   `ans.length == rains.length`
*   `ans[i] == -1` if `rains[i] > 0`.
*   `ans[i]` is the lake you choose to dry in the `ith` day if `rains[i] == 0`.

If there are multiple valid answers return **any** of them. If it is impossible to avoid flood return **an empty array**.

Notice that if you chose to dry a full lake, it becomes empty, but if you chose to dry an empty lake, nothing changes.

**Example 1:**

**Input:** rains = \[1,2,3,4\]
**Output:** \[-1,-1,-1,-1\]
**Explanation:** After the first day full lakes are \[1\]
After the second day full lakes are \[1,2\]
After the third day full lakes are \[1,2,3\]
After the fourth day full lakes are \[1,2,3,4\]
There's no day to dry any lake and there is no flood in any lake.

**Example 2:**

**Input:** rains = \[1,2,0,0,2,1\]
**Output:** \[-1,-1,2,1,-1,-1\]
**Explanation:** After the first day full lakes are \[1\]
After the second day full lakes are \[1,2\]
After the third day, we dry lake 2. Full lakes are \[1\]
After the fourth day, we dry lake 1. There is no full lakes.
After the fifth day, full lakes are \[2\].
After the sixth day, full lakes are \[1,2\].
It is easy that this scenario is flood-free. \[-1,-1,1,2,-1,-1\] is another acceptable scenario.

**Example 3:**

**Input:** rains = \[1,2,0,1,2\]
**Output:** \[\]
**Explanation:** After the second day, full lakes are  \[1,2\]. We have to dry one lake in the third day.
After that, it will rain over lakes \[1,2\]. It's easy to prove that no matter which lake you choose to dry in the 3rd day, the other one will flood.

**Constraints:**

*   `1 <= rains.length <= 105`
*   `0 <= rains[i] <= 109`

## A solution in Java

```java
int getPower(int x) {
    int steps = 0;
    while (x != 1) {
        if (x % 2 == 0) x /= 2;
        else x = 3 * x + 1;
        steps++;
    }
    return steps;
}

int sortByPower(int lo, int hi, int k) {
    List<int[]> nums = new ArrayList<>();
    for (int i = lo; i <= hi; i++) {
        nums.add(new int[]{getPower(i), i});
    }
    nums.sort(Comparator.comparingInt((int[] a) -> a[0]).thenComparingInt(a -> a[1]));
    return nums.get(k - 1)[1];
}
```
The algorithm starts with defining a helper function `getPower(x)` that takes an integer `x` and calculates its power value by following the given steps (divide by 2 if even, multiply by 3 and add 1 if odd) until `x` becomes 1. The function returns the number of steps required to reach 1.

Then, we define the main function `sort_by_power(lo, hi, k)` that generates a list of pairs (in Python, tuples) consisting of the power value and the integer itself for all integers in the range [lo, hi]. It then sorts this list in ascending order based on the power values (and the integers themselves as a tiebreaker).

Finally, the kth integer in the sorted list is returned as the result. This is achieved by indexing the sorted list with `k - 1` due to zero-based indexing.

## A solution in C++

```cpp
int getPower(int x) {
    int steps = 0;
    while (x != 1) {
        if (x % 2 == 0) x /= 2;
        else x = 3 * x + 1;
        steps++;
    }
    return steps;
}

int sort_by_power(int lo, int hi, int k) {
    vector<pair<int, int>> nums;
    for (int i = lo; i <= hi; i++) {
        nums.push_back({getPower(i), i});
    }
    sort(nums.begin(), nums.end());
    return nums[k - 1].second;
}
```
The algorithm starts with defining a helper function `getPower(x)` that takes an integer `x` and calculates its power value by following the given steps (divide by 2 if even, multiply by 3 and add 1 if odd) until `x` becomes 1. The function returns the number of steps required to reach 1.

Then, we define the main function `sort_by_power(lo, hi, k)` that generates a list of pairs (in Python, tuples) consisting of the power value and the integer itself for all integers in the range [lo, hi]. It then sorts this list in ascending order based on the power values (and the integers themselves as a tiebreaker).

Finally, the kth integer in the sorted list is returned as the result. This is achieved by indexing the sorted list with `k - 1` due to zero-based indexing.

## A solution in Python

```python
def get_power(x):
    steps = 0
    while x != 1:
        if x % 2 == 0:
            x //= 2
        else:
            x = 3 * x + 1
        steps += 1
    return steps

def sort_by_power(lo, hi, k):
    nums = [(get_power(i), i) for i in range(lo, hi + 1)]
    nums.sort()
    return nums[k - 1][1]
```
The algorithm starts with defining a helper function `getPower(x)` that takes an integer `x` and calculates its power value by following the given steps (divide by 2 if even, multiply by 3 and add 1 if odd) until `x` becomes 1. The function returns the number of steps required to reach 1.

Then, we define the main function `sort_by_power(lo, hi, k)` that generates a list of pairs (in Python, tuples) consisting of the power value and the integer itself for all integers in the range [lo, hi]. It then sorts this list in ascending order based on the power values (and the integers themselves as a tiebreaker).

Finally, the kth integer in the sorted list is returned as the result. This is achieved by indexing the sorted list with `k - 1` due to zero-based indexing.

## A solution in Javascript

```javascript
function getPower(x) {
    let steps = 0;
    while (x !== 1) {
        if (x % 2 === 0) x /= 2;
        else x = 3 * x + 1;
        steps++;
    }
    return steps;
}

function sortByPower(lo, hi, k) {
    let nums = [];
    for (let i = lo; i <= hi; i++) {
        nums.push([getPower(i), i]);
    }
    nums.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
    return nums[k - 1][1];
}
```
The algorithm starts with defining a helper function `getPower(x)` that takes an integer `x` and calculates its power value by following the given steps (divide by 2 if even, multiply by 3 and add 1 if odd) until `x` becomes 1. The function returns the number of steps required to reach 1.

Then, we define the main function `sort_by_power(lo, hi, k)` that generates a list of pairs (in Python, tuples) consisting of the power value and the integer itself for all integers in the range [lo, hi]. It then sorts this list in ascending order based on the power values (and the integers themselves as a tiebreaker).

Finally, the kth integer in the sorted list is returned as the result. This is achieved by indexing the sorted list with `k - 1` due to zero-based indexing.