# Constrained Subsequence Sum

- slug: constrained-subsequence-sum
- difficulty: Hard

Given an integer array `nums` and an integer `k`, return the maximum sum of a **non-empty** subsequence of that array such that for every two **consecutive** integers in the subsequence, `nums[i]` and `nums[j]`, where `i < j`, the condition `j - i <= k` is satisfied.

A _subsequence_ of an array is obtained by deleting some number of elements (can be zero) from the array, leaving the remaining elements in their original order.

**Example 1:**

**Input:** nums = \[10,2,-10,5,20\], k = 2
**Output:** 37
**Explanation:** The subsequence is \[10, 2, 5, 20\].

**Example 2:**

**Input:** nums = \[-1,-2,-3\], k = 1
**Output:** -1
**Explanation:** The subsequence must be non-empty, so we choose the largest number.

**Example 3:**

**Input:** nums = \[10,-2,-10,-5,20\], k = 2
**Output:** 23
**Explanation:** The subsequence is \[10, -2, -5, 20\].

**Constraints:**

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

## A solution in Java

```java
public int maxSum(int[] nums, int k) {
    int n = nums.length;
    PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
    long[] dp = new long[n + 1];
    long sum = 0;

    for (int i = 0; i < n; i++) {
        if (i >= k) pq.poll(); // Maintain the maximum size of k
        pq.offer((int)(dp[i] - nums[i]));
        dp[i + 1] = Math.max(dp[i], nums[i] + pq.peek());
        sum = Math.max(sum, dp[i + 1]);
    }

    return (int) sum;
}
```
We'll use dynamic programming to solve this problem. We use a variable `dp` to store the maximum subsequence sum ending at position `i`. We also use a priority queue `pq` to maintain the maximum size of `k` and hold the differences between `dp[i]` and `nums[i]`.

Iterating through the array, we first remove elements from `pq` when it is of size larger than `k`. Then, we add the difference between `dp[i]` and `nums[i]` into the priority queue. Next, we update `dp[i+1]` by selecting the maximum between `dp[i]` and the sum of `nums[i]` and the top element of the priority queue. This top element represents the maximum possible previous choice that satisfies the condition `j - i <= k`. Finally, we update the running maximum sum and continue iterating through the array.

Once the for loop is done, the maximum sum of a valid subsequence is stored in the `sum` variable. We return this value as the final answer.

## A solution in C++

```cpp
int maxSum(vector<int>& nums, int k) {
    int n = nums.size();
    priority_queue<int> pq;
    vector<long long> dp(n + 1, 0);
    long long sum = 0;

    for (int i = 0; i < n; ++i) {
        if (i >= k) pq.pop(); // Maintain the maximum size of k
        pq.push(dp[i] - nums[i]);
        dp[i + 1] = max(dp[i], nums[i] + pq.top());
        sum = max(sum, dp[i + 1]);
    }

    return sum;
}
```
We'll use dynamic programming to solve this problem. We use a variable `dp` to store the maximum subsequence sum ending at position `i`. We also use a priority queue `pq` to maintain the maximum size of `k` and hold the differences between `dp[i]` and `nums[i]`.

Iterating through the array, we first remove elements from `pq` when it is of size larger than `k`. Then, we add the difference between `dp[i]` and `nums[i]` into the priority queue. Next, we update `dp[i+1]` by selecting the maximum between `dp[i]` and the sum of `nums[i]` and the top element of the priority queue. This top element represents the maximum possible previous choice that satisfies the condition `j - i <= k`. Finally, we update the running maximum sum and continue iterating through the array.

Once the for loop is done, the maximum sum of a valid subsequence is stored in the `sum` variable. We return this value as the final answer.

## A solution in Python

```python
def maxSum(nums, k):
    n = len(nums)
    dp = [0] * (n + 1)
    pq = []
    sum_ = 0

    for i in range(n):
        if i >= k:
            pq.remove(-(dp[i] - nums[i]))  # Remove element from pq
        heapq.heappush(pq, -(dp[i] - nums[i]))  # Push in the negative for max heap
        dp[i + 1] = max(dp[i], nums[i] - pq[0])
        sum_ = max(sum_, dp[i + 1])

    return sum_
```
We'll use dynamic programming to solve this problem. We use a variable `dp` to store the maximum subsequence sum ending at position `i`. We also use a priority queue `pq` to maintain the maximum size of `k` and hold the differences between `dp[i]` and `nums[i]`.

Iterating through the array, we first remove elements from `pq` when it is of size larger than `k`. Then, we add the difference between `dp[i]` and `nums[i]` into the priority queue. Next, we update `dp[i+1]` by selecting the maximum between `dp[i]` and the sum of `nums[i]` and the top element of the priority queue. This top element represents the maximum possible previous choice that satisfies the condition `j - i <= k`. Finally, we update the running maximum sum and continue iterating through the array.

Once the for loop is done, the maximum sum of a valid subsequence is stored in the `sum` variable. We return this value as the final answer.

## A solution in Javascript

```javascript
function maxSum(nums, k) {
    const n = nums.length;
    const pq = new PriorityQueue((a, b) => b - a);
    const dp = new Array(n + 1).fill(0);
    let sum = 0;

    for (let i = 0; i < n; i++) {
        if (i >= k) pq.poll(); // Maintain the maximum size of k
        pq.offer(dp[i] - nums[i]);
        dp[i + 1] = Math.max(dp[i], nums[i] + pq.peek());
        sum = Math.max(sum, dp[i + 1]);
    }

    return sum;
}

class PriorityQueue {
    constructor(comparator = (a, b) => a - b) {
        this._heap = [];
        this._comparator = comparator;
    }

    size() {
        return this._heap.length;
    }

    isEmpty() {
        return this.size() === 0;
    }

    peek() {
        return this._heap[0];
    }

    push(value) {
        this._heap.push(value);
        this._shiftUp();
    }

    poll() {
        const rootNode = this.peek();
        this._heap[0] = this._heap.pop();
        this._shiftDown();
        return rootNode;
    }

    _parent(idx) {
        return Math.floor((idx - 1) / 2);
    }

    _left(idx) {
        return idx * 2 + 1;
    }

    _right(idx) {
        return idx * 2 + 2;
    }

    _hasLeft(idx) {
        return this._left(idx) < this._heap.length;
    }

    _hasRight(idx) {
        return this._right(idx) < this._heap.length;
    }

    _shiftUp() {
        let nodeIdx = this.size() - 1;
        while (
            nodeIdx > 0 &&
            this._comparator(this._heap[nodeIdx], this._heap[this._parent(nodeIdx)]) < 0
        ) {
            this._swap(nodeIdx, this._parent(nodeIdx));
            nodeIdx = this._parent(nodeIdx);
        }
    }

    _shiftDown() {
        let nodeIdx = 0;
        while (this._hasLeft(nodeIdx)) {
            let smallerChildIdx = this._left(nodeIdx);
            if (
                this._hasRight(nodeIdx) &&
                this._comparator(this._heap[this._right(nodeIdx)], this._heap[this._left(nodeIdx)]) < 0
            ) {
                smallerChildIdx = this._right(nodeIdx);
            }
            if (this._comparator(this._heap[nodeIdx], this._heap[smallerChildIdx]) < 0) {
                break;
            }
            this._swap(smallerChildIdx, nodeIdx);
            nodeIdx = smallerChildIdx;
        }
    }

    _swap(i, j) {
        const tmp = this._heap[i];
        this._heap[i] = this._heap[j];
        this._heap[j] = tmp;
    }
}
```
We'll use dynamic programming to solve this problem. We use a variable `dp` to store the maximum subsequence sum ending at position `i`. We also use a priority queue `pq` to maintain the maximum size of `k` and hold the differences between `dp[i]` and `nums[i]`.

Iterating through the array, we first remove elements from `pq` when it is of size larger than `k`. Then, we add the difference between `dp[i]` and `nums[i]` into the priority queue. Next, we update `dp[i+1]` by selecting the maximum between `dp[i]` and the sum of `nums[i]` and the top element of the priority queue. This top element represents the maximum possible previous choice that satisfies the condition `j - i <= k`. Finally, we update the running maximum sum and continue iterating through the array.

Once the for loop is done, the maximum sum of a valid subsequence is stored in the `sum` variable. We return this value as the final answer.


# Counting Elements

- slug: counting-elements
- difficulty: Easy

Given an integer array `arr`, count how many elements `x` there are, such that `x + 1` is also in `arr`. If there are duplicates in `arr`, count them separately.

**Example 1:**

**Input:** arr = \[1,2,3\]
**Output:** 2
**Explanation:** 1 and 2 are counted cause 2 and 3 are in arr.

**Example 2:**

**Input:** arr = \[1,1,3,3,5,5,7,7\]
**Output:** 0
**Explanation:** No numbers are counted, cause there is no 2, 4, 6, or 8 in arr.

**Constraints:**

*   `1 <= arr.length <= 1000`
*   `0 <= arr[i] <= 1000`

## A solution in Java

```java
public int[] sumZero(int n) {
    int[] res = new int[n];
    for (int i = 1; i <= n / 2; i++) {
        res[i - 1] = i;
        res[n - i] = -i;
    }
    return res;
}
```
The algorithm iterates from 1 to n/2 (inclusive). For each number i, it appends both i and -i to the result array, making their sum equal to 0. If the given integer n is odd, then there is one more number remaining which is 0, so we append 0 to the result array. By doing this, we create a unique array of integers adding up to 0. The time complexity of this algorithm is O(n/2) = O(n), and the space complexity is also O(n) as the size of the result array is equal to the given input n.

## A solution in C++

```cpp
#include <vector>

std::vector<int> sumZero(int n) {
    std::vector<int> res;
    for (int i = 1; i <= n / 2; i++) {
        res.push_back(i);
        res.push_back(-i);
    }
    if (n % 2 != 0) {
        res.push_back(0);
    }
    return res;
}
```
The algorithm iterates from 1 to n/2 (inclusive). For each number i, it appends both i and -i to the result array, making their sum equal to 0. If the given integer n is odd, then there is one more number remaining which is 0, so we append 0 to the result array. By doing this, we create a unique array of integers adding up to 0. The time complexity of this algorithm is O(n/2) = O(n), and the space complexity is also O(n) as the size of the result array is equal to the given input n.

## A solution in Python

```python
def sum_zero(n):
    res = []
    for i in range(1, (n // 2) + 1):
        res.append(i)
        res.append(-i)
    if n % 2 != 0:
        res.append(0)
    return res
```
The algorithm iterates from 1 to n/2 (inclusive). For each number i, it appends both i and -i to the result array, making their sum equal to 0. If the given integer n is odd, then there is one more number remaining which is 0, so we append 0 to the result array. By doing this, we create a unique array of integers adding up to 0. The time complexity of this algorithm is O(n/2) = O(n), and the space complexity is also O(n) as the size of the result array is equal to the given input n.

## A solution in Javascript

```javascript
function sumZero(n) {
    const res = [];
    for (let i = 1; i <= Math.floor(n / 2); i++) {
        res.push(i);
        res.push(-i);
    }
    if (n % 2 !== 0) {
        res.push(0);
    }
    return res;
}
```
The algorithm iterates from 1 to n/2 (inclusive). For each number i, it appends both i and -i to the result array, making their sum equal to 0. If the given integer n is odd, then there is one more number remaining which is 0, so we append 0 to the result array. By doing this, we create a unique array of integers adding up to 0. The time complexity of this algorithm is O(n/2) = O(n), and the space complexity is also O(n) as the size of the result array is equal to the given input n.


# Perform String Shifts

- slug: perform-string-shifts
- difficulty: Easy

You are given a string `s` containing lowercase English letters, and a matrix `shift`, where `shift[i] = [directioni, amounti]`:

*   `directioni` can be `0` (for left shift) or `1` (for right shift).
*   `amounti` is the amount by which string `s` is to be shifted.
*   A left shift by 1 means remove the first character of `s` and append it to the end.
*   Similarly, a right shift by 1 means remove the last character of `s` and add it to the beginning.

Return the final string after all operations.

**Example 1:**

**Input:** s =  "abc ", shift = \[\[0,1\],\[1,2\]\]
**Output:**  "cab "
**Explanation:**
\[0,1\] means shift to left by 1.  "abc " ->  "bca "
\[1,2\] means shift to right by 2.  "bca " ->  "cab "

**Example 2:**

**Input:** s =  "abcdefg ", shift = \[\[1,1\],\[1,1\],\[0,2\],\[1,3\]\]
**Output:**  "efgabcd "
**Explanation:**
\[1,1\] means shift to right by 1.  "abcdefg " ->  "gabcdef "
\[1,1\] means shift to right by 1.  "gabcdef " ->  "fgabcde "
\[0,2\] means shift to left by 2.  "fgabcde " ->  "abcdefg "
\[1,3\] means shift to right by 3.  "abcdefg " ->  "efgabcd "

**Constraints:**

*   `1 <= s.length <= 100`
*   `s` only contains lower case English letters.
*   `1 <= shift.length <= 100`
*   `shift[i].length == 2`
*   `directioni` is either `0` or `1`.
*   `0 <= amounti <= 100`

## A solution in Java

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

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int v) { val = v; }
}

public List<Integer> inorder(TreeNode root, List<Integer> output) {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode current = root;

    while (current != null || !stack.isEmpty()) {
        while (current != null) {
            stack.push(current);
            current = current.left;
        }
        current = stack.pop();
        output.add(current.val);
        current = current.right;
    }

    return output;
}

public List<Integer> getAllElements(TreeNode root1, TreeNode root2) {
    List<Integer> tree1 = new ArrayList<>();
    List<Integer> tree2 = new ArrayList<>();
    inorder(root1, tree1);
    inorder(root2, tree2);

    List<Integer> result = new ArrayList<>();
    int i = 0, j = 0;
    while (i < tree1.size() || j < tree2.size()) {
        if (i < tree1.size() && (j >= tree2.size() || tree1.get(i) <= tree2.get(j))) {
            result.add(tree1.get(i++));
        } else {
            result.add(tree2.get(j++));
        }
    }

    return result;
}
```
1. Create a helper function, `inorder`, which takes a root node and returns the inorder traversal of the tree, in the form of an array/vector/list.
2. The `inorder` function uses a stack and a while loop to iterate through each node. It starts with the left-most node and iterates through to the right-most node.
3. Call the `inorder` function on both `root1` and `root2` and store the results in two separate arrays.
4. Initialize two pointers `i` and `j` and iterate through both arrays together.
5. Compare the current element of both arrays, and push the smaller element onto the result array, incrementing the corresponding pointer.
6. If one array reaches the end, push the remaining elements from the other array to the result array.
7. Return the result array containing the sorted elements from both trees.

## A solution in C++

```cpp
#include <vector>
#include <stack>

using namespace std;

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int v) : val(v), left(nullptr), right(nullptr) {}
};

void inorder(TreeNode* root, vector<int>& output) {
    stack<TreeNode*> s;
    TreeNode* current = root;

    while (current || !s.empty()) {
        while (current) {
            s.push(current);
            current = current->left;
        }
        current = s.top();
        s.pop();
        output.push_back(current->val);
        current = current->right;
    }
}

vector<int> getAllElements(TreeNode* root1, TreeNode* root2) {
    vector<int> tree1, tree2;
    inorder(root1, tree1);
    inorder(root2, tree2);

    vector<int> result;
    int i = 0, j = 0;
    while (i < tree1.size() || j < tree2.size()) {
        if (i < tree1.size() && (j >= tree2.size() || tree1[i] <= tree2[j])) {
            result.push_back(tree1[i++]);
        } else {
            result.push_back(tree2[j++]);
        }
    }

    return result;
}
```
1. Create a helper function, `inorder`, which takes a root node and returns the inorder traversal of the tree, in the form of an array/vector/list.
2. The `inorder` function uses a stack and a while loop to iterate through each node. It starts with the left-most node and iterates through to the right-most node.
3. Call the `inorder` function on both `root1` and `root2` and store the results in two separate arrays.
4. Initialize two pointers `i` and `j` and iterate through both arrays together.
5. Compare the current element of both arrays, and push the smaller element onto the result array, incrementing the corresponding pointer.
6. If one array reaches the end, push the remaining elements from the other array to the result array.
7. Return the result array containing the sorted elements from both trees.

## A solution in Python

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

def inorder(root):
    output = []
    stack = []
    current = root

    while current or stack:
        while current:
            stack.append(current)
            current = current.left
        current = stack.pop()
        output.append(current.val)
        current = current.right

    return output

def getAllElements(root1, root2):
    tree1 = inorder(root1)
    tree2 = inorder(root2)
    result = []
    i, j = 0, 0

    while i < len(tree1) or j < len(tree2):
        if i < len(tree1) and (j >= len(tree2) or tree1[i] <= tree2[j]):
            result.append(tree1[i])
            i += 1
        else:
            result.append(tree2[j])
            j += 1

    return result
```
1. Create a helper function, `inorder`, which takes a root node and returns the inorder traversal of the tree, in the form of an array/vector/list.
2. The `inorder` function uses a stack and a while loop to iterate through each node. It starts with the left-most node and iterates through to the right-most node.
3. Call the `inorder` function on both `root1` and `root2` and store the results in two separate arrays.
4. Initialize two pointers `i` and `j` and iterate through both arrays together.
5. Compare the current element of both arrays, and push the smaller element onto the result array, incrementing the corresponding pointer.
6. If one array reaches the end, push the remaining elements from the other array to the result array.
7. Return the result array containing the sorted elements from both trees.

## A solution in Javascript

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

function inorder(root) {
    const output = [];
    const stack = [];
    let current = root;

    while (current || stack.length) {
        while (current) {
            stack.push(current);
            current = current.left;
        }
        current = stack.pop();
        output.push(current.val);
        current = current.right;
    }

    return output;
}

function getAllElements(root1, root2) {
    const tree1 = inorder(root1);
    const tree2 = inorder(root2);
    const result = [];
    let i = 0, j = 0;

    while (i < tree1.length || j < tree2.length) {
        if (i < tree1.length && (j >= tree2.length || tree1[i] <= tree2[j])) {
            result.push(tree1[i++]);
        } else {
            result.push(tree2[j++]);
        }
    }

    return result;
}
```
1. Create a helper function, `inorder`, which takes a root node and returns the inorder traversal of the tree, in the form of an array/vector/list.
2. The `inorder` function uses a stack and a while loop to iterate through each node. It starts with the left-most node and iterates through to the right-most node.
3. Call the `inorder` function on both `root1` and `root2` and store the results in two separate arrays.
4. Initialize two pointers `i` and `j` and iterate through both arrays together.
5. Compare the current element of both arrays, and push the smaller element onto the result array, incrementing the corresponding pointer.
6. If one array reaches the end, push the remaining elements from the other array to the result array.
7. Return the result array containing the sorted elements from both trees.


# Leftmost Column with at Least a One

- slug: leftmost-column-with-at-least-a-one
- difficulty: Medium

A **row-sorted binary matrix** means that all elements are `0` or `1` and each row of the matrix is sorted in non-decreasing order.

Given a **row-sorted binary matrix** `binaryMatrix`, return _the index (0-indexed) of the **leftmost column** with a 1 in it_. If such an index does not exist, return `-1`.

**You can't access the Binary Matrix directly.** You may only access the matrix using a `BinaryMatrix` interface:

*   `BinaryMatrix.get(row, col)` returns the element of the matrix at index `(row, col)` (0-indexed).
*   `BinaryMatrix.dimensions()` returns the dimensions of the matrix as a list of 2 elements `[rows, cols]`, which means the matrix is `rows x cols`.

Submissions making more than `1000` calls to `BinaryMatrix.get` will be judged _Wrong Answer_. Also, any solutions that attempt to circumvent the judge will result in disqualification.

For custom testing purposes, the input will be the entire binary matrix `mat`. You will not have access to the binary matrix directly.

**Example 1:**

**Input:** mat = \[\[0,0\],\[1,1\]\]
**Output:** 0

**Example 2:**

**Input:** mat = \[\[0,0\],\[0,1\]\]
**Output:** 1

**Example 3:**

**Input:** mat = \[\[0,0\],\[0,0\]\]
**Output:** -1

**Constraints:**

*   `rows == mat.length`
*   `cols == mat[i].length`
*   `1 <= rows, cols <= 100`
*   `mat[i][j]` is either `0` or `1`.
*   `mat[i]` is sorted in non-decreasing order.

## A solution in Java

```java
boolean canReach(int[] arr, int start) {
    if (start >= 0 && start < arr.length && arr[start] >= 0) {
        if (arr[start] == 0)
            return true;

        arr[start] = -arr[start];
        return canReach(arr, start + arr[start]) || canReach(arr, start - arr[start]);
    }
    return false;
}
```
The algorithm uses a depth-first search approach. At each index `i`, it checks if it's within the bounds of the array and if the value at the current index is non-negative.

If the current value is 0, it returns true because the goal is reached.
If not, it marks the current position as visited by negating the value and then checks if it can reach 0 with the available jump choices, `i + arr[i]` or `i - arr[i]`.

The function returns false if no valid path was found that reaches the 0 value.

## A solution in C++

```cpp
bool canReach(vector<int> &arr, int start) {
    if (start >= 0 && start < arr.size() && arr[start] >= 0) {
        if (arr[start] == 0)
            return true;

        arr[start] = -arr[start];
        return canReach(arr, start + arr[start]) || canReach(arr, start - arr[start]);
    }
    return false;
}
```
The algorithm uses a depth-first search approach. At each index `i`, it checks if it's within the bounds of the array and if the value at the current index is non-negative.

If the current value is 0, it returns true because the goal is reached.
If not, it marks the current position as visited by negating the value and then checks if it can reach 0 with the available jump choices, `i + arr[i]` or `i - arr[i]`.

The function returns false if no valid path was found that reaches the 0 value.

## A solution in Python

```python
def canReach(arr: List[int], start: int) -> bool:
    if 0 <= start < len(arr) and arr[start] >= 0:
        if arr[start] == 0:
            return True

        jump = arr[start]
        arr[start] = -arr[start]
        return canReach(arr, start + jump) or canReach(arr, start - jump)
    return False
```
The algorithm uses a depth-first search approach. At each index `i`, it checks if it's within the bounds of the array and if the value at the current index is non-negative.

If the current value is 0, it returns true because the goal is reached.
If not, it marks the current position as visited by negating the value and then checks if it can reach 0 with the available jump choices, `i + arr[i]` or `i - arr[i]`.

The function returns false if no valid path was found that reaches the 0 value.

## A solution in Javascript

```javascript
function canReach(arr, start) {
    if (start >= 0 && start < arr.length && arr[start] >= 0) {
        if (arr[start] === 0)
            return true;

        let jump = arr[start];
        arr[start] = -arr[start];
        return canReach(arr, start + jump) || canReach(arr, start - jump);
    }
    return false;
}
```
The algorithm uses a depth-first search approach. At each index `i`, it checks if it's within the bounds of the array and if the value at the current index is non-negative.

If the current value is 0, it returns true because the goal is reached.
If not, it marks the current position as visited by negating the value and then checks if it can reach 0 with the available jump choices, `i + arr[i]` or `i - arr[i]`.

The function returns false if no valid path was found that reaches the 0 value.


# First Unique Number

- slug: first-unique-number
- difficulty: Medium

You have a queue of integers, you need to retrieve the first unique integer in the queue.

Implement the `FirstUnique` class:

*   `FirstUnique(int[] nums)` Initializes the object with the numbers in the queue.
*   `int showFirstUnique()` returns the value of **the first unique** integer of the queue, and returns **\-1** if there is no such integer.
*   `void add(int value)` insert value to the queue.

**Example 1:**

**Input:**
\[ "FirstUnique ", "showFirstUnique ", "add ", "showFirstUnique ", "add ", "showFirstUnique ", "add ", "showFirstUnique "\]
\[\[\[2,3,5\]\],\[\],\[5\],\[\],\[2\],\[\],\[3\],\[\]\]
**Output:**
\[null,2,null,2,null,3,null,-1\]
**Explanation:**
FirstUnique firstUnique = new FirstUnique(\[2,3,5\]);
firstUnique.showFirstUnique(); // return 2
firstUnique.add(5);            // the queue is now \[2,3,5,5\]
firstUnique.showFirstUnique(); // return 2
firstUnique.add(2);            // the queue is now \[2,3,5,5,2\]
firstUnique.showFirstUnique(); // return 3
firstUnique.add(3);            // the queue is now \[2,3,5,5,2,3\]
firstUnique.showFirstUnique(); // return -1

**Example 2:**

**Input:**
\[ "FirstUnique ", "showFirstUnique ", "add ", "add ", "add ", "add ", "add ", "showFirstUnique "\]
\[\[\[7,7,7,7,7,7\]\],\[\],\[7\],\[3\],\[3\],\[7\],\[17\],\[\]\]
**Output:**
\[null,-1,null,null,null,null,null,17\]
**Explanation:**
FirstUnique firstUnique = new FirstUnique(\[7,7,7,7,7,7\]);
firstUnique.showFirstUnique(); // return -1
firstUnique.add(7);            // the queue is now \[7,7,7,7,7,7,7\]
firstUnique.add(3);            // the queue is now \[7,7,7,7,7,7,7,3\]
firstUnique.add(3);            // the queue is now \[7,7,7,7,7,7,7,3,3\]
firstUnique.add(7);            // the queue is now \[7,7,7,7,7,7,7,3,3,7\]
firstUnique.add(17);           // the queue is now \[7,7,7,7,7,7,7,3,3,7,17\]
firstUnique.showFirstUnique(); // return 17

**Example 3:**

**Input:**
\[ "FirstUnique ", "showFirstUnique ", "add ", "showFirstUnique "\]
\[\[\[809\]\],\[\],\[809\],\[\]\]
**Output:**
\[null,809,null,-1\]
**Explanation:**
FirstUnique firstUnique = new FirstUnique(\[809\]);
firstUnique.showFirstUnique(); // return 809
firstUnique.add(809);          // the queue is now \[809,809\]
firstUnique.showFirstUnique(); // return -1

**Constraints:**

*   `1 <= nums.length <= 10^5`
*   `1 <= nums[i] <= 10^8`
*   `1 <= value <= 10^8`
*   At most `50000` calls will be made to `showFirstUnique` and `add`.

## A solution in Java

```java
import java.util.Map;

public boolean isSolvable(Map<Character, Integer> words, int result) {
    int sum = 0;
    for (int value : words.values()) {
        sum += value;
    }
    return sum % 10 == result % 10;
}
```
The problem states that we need to check if the given equation is solvable based on a given mapping of characters to integers. The best data structure to represent this mapping is a dictionary (or map) for each language.

The algorithm is as follows:

1. For each character in the words (left side of the equation), get the corresponding integer value from the map and add it to a sum variable.
2. Check if the sum of the left side modulo 10 is equal to the right side of the equation modulo 10. If they are equal, return `true`, otherwise return `false`.

The reason for using the modulo operation is to ensure that the sum of the left side does not exceed the range of single-digit numbers, which is a constraint of the problem.

## A solution in C++

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

bool isSolvable(std::map<char, int> words, int result) {
    int sum = 0;
    for (auto const& word : words) {
        sum += word.second;
    }
    return sum % 10 == result % 10;
}
```
The problem states that we need to check if the given equation is solvable based on a given mapping of characters to integers. The best data structure to represent this mapping is a dictionary (or map) for each language.

The algorithm is as follows:

1. For each character in the words (left side of the equation), get the corresponding integer value from the map and add it to a sum variable.
2. Check if the sum of the left side modulo 10 is equal to the right side of the equation modulo 10. If they are equal, return `true`, otherwise return `false`.

The reason for using the modulo operation is to ensure that the sum of the left side does not exceed the range of single-digit numbers, which is a constraint of the problem.

## A solution in Python

```python
def is_solvable(words, result):
    return sum(words.values()) % 10 == result % 10
```
The problem states that we need to check if the given equation is solvable based on a given mapping of characters to integers. The best data structure to represent this mapping is a dictionary (or map) for each language.

The algorithm is as follows:

1. For each character in the words (left side of the equation), get the corresponding integer value from the map and add it to a sum variable.
2. Check if the sum of the left side modulo 10 is equal to the right side of the equation modulo 10. If they are equal, return `true`, otherwise return `false`.

The reason for using the modulo operation is to ensure that the sum of the left side does not exceed the range of single-digit numbers, which is a constraint of the problem.

## A solution in Javascript

```javascript
function isSolvable(words, result) {
    let sum = 0;
    for (let key in words) {
        sum += words[key];
    }
    return sum % 10 === result % 10;
}
```
The problem states that we need to check if the given equation is solvable based on a given mapping of characters to integers. The best data structure to represent this mapping is a dictionary (or map) for each language.

The algorithm is as follows:

1. For each character in the words (left side of the equation), get the corresponding integer value from the map and add it to a sum variable.
2. Check if the sum of the left side modulo 10 is equal to the right side of the equation modulo 10. If they are equal, return `true`, otherwise return `false`.

The reason for using the modulo operation is to ensure that the sum of the left side does not exceed the range of single-digit numbers, which is a constraint of the problem.


# Check If a String Is a Valid Sequence from Root to Leaves Path in a Binary Tree

- slug: check-if-a-string-is-a-valid-sequence-from-root-to-leaves-path-in-a-binary-tree
- difficulty: Medium

Given a binary tree where each path going from the root to any leaf form a **valid sequence**, check if a given string is a **valid sequence** in such binary tree.

We get the given string from the concatenation of an array of integers `arr` and the concatenation of all values of the nodes along a path results in a **sequence** in the given binary tree.

**Example 1:**

**Input:** root = \[0,1,0,0,1,0,null,null,1,0,0\], arr = \[0,1,0,1\]
**Output:** true
**Explanation:**
The path 0 -> 1 -> 0 -> 1 is a valid sequence (green color in the figure).
Other valid sequences are:
0 -> 1 -> 1 -> 0
0 -> 0 -> 0

**Example 2:**

**Input:** root = \[0,1,0,0,1,0,null,null,1,0,0\], arr = \[0,0,1\]
**Output:** false
**Explanation:** The path 0 -> 0 -> 1 does not exist, therefore it is not even a sequence.

**Example 3:**

**Input:** root = \[0,1,0,0,1,0,null,null,1,0,0\], arr = \[0,1,1\]
**Output:** false
**Explanation:** The path 0 -> 1 -> 1 is a sequence, but it is not a valid sequence.

**Constraints:**

*   `1 <= arr.length <= 5000`
*   `0 <= arr[i] <= 9`
*   Each node's value is between \[0 - 9\].

## A solution in Java

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

public boolean isValidSequence(TreeNode root, int[] arr, int index) {
    if (root == null || index >= arr.length || arr[index] != root.val) {
        return false;
    }
    if (root.left == null && root.right == null) {
        return index == arr.length - 1;
    }
    return isValidSequence(root.left, arr, index + 1) || isValidSequence(root.right, arr, index + 1);
}
```
The algorithm uses a Depth-First Search (DFS) approach to traverse the given binary tree. We pass the current root node, the input array `arr`, and the current index (starting with 0) into the `isValidSequence` function.

We use recursion to traverse the tree, checking the following conditions:
- If the current root node is null, or the current index is out of bounds of the array, or the current node value is not equal to the array value at the current index, then we return false since this is not a valid sequence.
- If the current root node is a leaf node (both left and right children are null), we check if the current index is the last index in the array. If it is, then the path is a valid sequence and we return true; otherwise, we return false.
- For non-leaf nodes, we recursively call the `isValidSequence` function on the left and right children of the current node, increasing the index by 1. If either of these recursive calls return true, the overall result is true; otherwise, the result is false.

## A solution in C++

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

bool isValidSequence(TreeNode* root, vector<int>& arr, int index = 0) {
    if (root == nullptr || index >= arr.size() || arr[index] != root->val) {
        return false;
    }
    if (root->left == nullptr && root->right == nullptr) {
        return index == arr.size() - 1;
    }
    return isValidSequence(root->left, arr, index + 1) || isValidSequence(root->right, arr, index + 1);
}
```
The algorithm uses a Depth-First Search (DFS) approach to traverse the given binary tree. We pass the current root node, the input array `arr`, and the current index (starting with 0) into the `isValidSequence` function.

We use recursion to traverse the tree, checking the following conditions:
- If the current root node is null, or the current index is out of bounds of the array, or the current node value is not equal to the array value at the current index, then we return false since this is not a valid sequence.
- If the current root node is a leaf node (both left and right children are null), we check if the current index is the last index in the array. If it is, then the path is a valid sequence and we return true; otherwise, we return false.
- For non-leaf nodes, we recursively call the `isValidSequence` function on the left and right children of the current node, increasing the index by 1. If either of these recursive calls return true, the overall result is true; otherwise, the result is false.

## A solution in Python

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

def isValidSequence(root, arr, index=0):
    if not root or index >= len(arr) or arr[index] != root.val:
        return False
    if not root.left and not root.right:
        return index == len(arr) - 1
    return isValidSequence(root.left, arr, index + 1) or isValidSequence(root.right, arr, index + 1)
```
The algorithm uses a Depth-First Search (DFS) approach to traverse the given binary tree. We pass the current root node, the input array `arr`, and the current index (starting with 0) into the `isValidSequence` function.

We use recursion to traverse the tree, checking the following conditions:
- If the current root node is null, or the current index is out of bounds of the array, or the current node value is not equal to the array value at the current index, then we return false since this is not a valid sequence.
- If the current root node is a leaf node (both left and right children are null), we check if the current index is the last index in the array. If it is, then the path is a valid sequence and we return true; otherwise, we return false.
- For non-leaf nodes, we recursively call the `isValidSequence` function on the left and right children of the current node, increasing the index by 1. If either of these recursive calls return true, the overall result is true; otherwise, the result is false.

## A solution in Javascript

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

function isValidSequence(root, arr, index = 0) {
    if (!root || index >= arr.length || arr[index] !== root.val) {
        return false;
    }
    if (!root.left && !root.right) {
        return index === arr.length - 1;
    }
    return isValidSequence(root.left, arr, index + 1) || isValidSequence(root.right, arr, index + 1);
}
```
The algorithm uses a Depth-First Search (DFS) approach to traverse the given binary tree. We pass the current root node, the input array `arr`, and the current index (starting with 0) into the `isValidSequence` function.

We use recursion to traverse the tree, checking the following conditions:
- If the current root node is null, or the current index is out of bounds of the array, or the current node value is not equal to the array value at the current index, then we return false since this is not a valid sequence.
- If the current root node is a leaf node (both left and right children are null), we check if the current index is the last index in the array. If it is, then the path is a valid sequence and we return true; otherwise, we return false.
- For non-leaf nodes, we recursively call the `isValidSequence` function on the left and right children of the current node, increasing the index by 1. If either of these recursive calls return true, the overall result is true; otherwise, the result is false.


# Kids With the Greatest Number of Candies

- slug: kids-with-the-greatest-number-of-candies
- difficulty: Easy

There are `n` kids with candies. You are given an integer array `candies`, where each `candies[i]` represents the number of candies the `ith` kid has, and an integer `extraCandies`, denoting the number of extra candies that you have.

Return _a boolean array_ `result` _of length_ `n`_, where_ `result[i]` _is_ `true` _if, after giving the_ `ith` _kid all the_ `extraCandies`_, they will have the **greatest** number of candies among all the kids__, or_ `false` _otherwise_.

Note that **multiple** kids can have the **greatest** number of candies.

**Example 1:**

**Input:** candies = \[2,3,5,1,3\], extraCandies = 3
**Output:** \[true,true,true,false,true\]
**Explanation:** If you give all extraCandies to:
- Kid 1, they will have 2 + 3 = 5 candies, which is the greatest among the kids.
- Kid 2, they will have 3 + 3 = 6 candies, which is the greatest among the kids.
- Kid 3, they will have 5 + 3 = 8 candies, which is the greatest among the kids.
- Kid 4, they will have 1 + 3 = 4 candies, which is not the greatest among the kids.
- Kid 5, they will have 3 + 3 = 6 candies, which is the greatest among the kids.

**Example 2:**

**Input:** candies = \[4,2,1,1,2\], extraCandies = 1
**Output:** \[true,false,false,false,false\]
**Explanation:** There is only 1 extra candy.
Kid 1 will always have the greatest number of candies, even if a different kid is given the extra candy.

**Example 3:**

**Input:** candies = \[12,1,12\], extraCandies = 10
**Output:** \[true,false,true\]

**Constraints:**

*   `n == candies.length`
*   `2 <= n <= 100`
*   `1 <= candies[i] <= 100`
*   `1 <= extraCandies <= 50`

## A solution in Java

```java
import java.util.*;

public class DAGAncestors {
    public static void findAncestors(int node, List<List<Integer>> adjList, boolean[] visited, List<Integer> ancestors) {
        if (visited[node]) return;
        visited[node] = true;
        for (int ancestor : adjList.get(node)) {
            ancestors.add(ancestor);
            findAncestors(ancestor, adjList, visited, ancestors);
        }
    }

    public static List<List<Integer>> findAncestorsInDAG(int n, int[][] edges) {
        List<List<Integer>> adjList = new ArrayList<>();
        List<List<Integer>> ans = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            adjList.add(new ArrayList<>());
            ans.add(new ArrayList<>());
        }
        for (int[] edge : edges) {
            adjList.get(edge[1]).add(edge[0]);
        }
        for (int i = 0; i < n; ++i) {
            boolean[] visited = new boolean[n];
            findAncestors(i, adjList, visited, ans.get(i));
            Collections.sort(ans.get(i));
        }
        return ans;
    }
}
```
The algorithm works by iterating over all the given nodes and finding the ancestors of each node.
1. Create an adjacency list representation of the graph where the keys are the nodes and the values are lists of their parents.
2. For each node `i` in the graph, perform a Depth-First Search using a helper function `findAncestors()`, to explore all the ancestors by traversing the parent nodes.
3. During the search, maintain a `visited` array to prevent infinite loops and avoid visiting already visited nodes.
4. Append the ancestors of each node to a list and sort it in ascending order.
5. Return the list of ancestors for all nodes as a nested list.

## A solution in C++

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

void findAncestors(int node, vector<vector<int>>& adj_list, vector<bool>& visited, vector<int>& ans) {
    if (visited[node]) return;
    visited[node] = true;
    for (int ancestor : adj_list[node]) {
        ans.push_back(ancestor);
        findAncestors(ancestor, adj_list, visited, ans);
    }
}

vector<vector<int>> findAncestorsInDAG(int n, vector<vector<int>>& edges) {
    vector<vector<int>> adj_list(n), ans(n);
    for (vector<int>& edge : edges) {
        adj_list[edge[1]].push_back(edge[0]);
    }
    for (int i = 0; i < n; ++i) {
        vector<bool> visited(n, false);
        findAncestors(i, adj_list, visited, ans[i]);
        sort(ans[i].begin(), ans[i].end());
    }
    return ans;
}
```
The algorithm works by iterating over all the given nodes and finding the ancestors of each node.
1. Create an adjacency list representation of the graph where the keys are the nodes and the values are lists of their parents.
2. For each node `i` in the graph, perform a Depth-First Search using a helper function `findAncestors()`, to explore all the ancestors by traversing the parent nodes.
3. During the search, maintain a `visited` array to prevent infinite loops and avoid visiting already visited nodes.
4. Append the ancestors of each node to a list and sort it in ascending order.
5. Return the list of ancestors for all nodes as a nested list.

## A solution in Python

```python
from collections import defaultdict

def find_ancestors(node, adj_list, visited, ans):
    if visited[node]:
        return
    visited[node] = True
    for ancestor in adj_list[node]:
        ans.append(ancestor)
        find_ancestors(ancestor, adj_list, visited, ans)

def find_ancestors_in_dag(n, edges):
    adj_list = defaultdict(list)
    for edge in edges:
        adj_list[edge[1]].append(edge[0])
    ans = []
    for i in range(n):
        visited = [False] * n
        ancestors = []
        find_ancestors(i, adj_list, visited, ancestors)
        ans.append(sorted(ancestors))
    return ans
```
The algorithm works by iterating over all the given nodes and finding the ancestors of each node.
1. Create an adjacency list representation of the graph where the keys are the nodes and the values are lists of their parents.
2. For each node `i` in the graph, perform a Depth-First Search using a helper function `findAncestors()`, to explore all the ancestors by traversing the parent nodes.
3. During the search, maintain a `visited` array to prevent infinite loops and avoid visiting already visited nodes.
4. Append the ancestors of each node to a list and sort it in ascending order.
5. Return the list of ancestors for all nodes as a nested list.

## A solution in Javascript

```javascript
function findAncestors(node, adjList, visited, ancestors) {
    if (visited[node]) return;
    visited[node] = true;
    for (const ancestor of adjList[node]) {
        ancestors.push(ancestor);
        findAncestors(ancestor, adjList, visited, ancestors);
    }
}

function findAncestorsInDAG(n, edges) {
    const adjList = new Array(n).fill(0).map(() => []);
    const ans = new Array(n).fill(0).map(() => []);
    for (const edge of edges) {
        adjList[edge[1]].push(edge[0]);
    }
    for (let i = 0; i < n; ++i) {
        const visited = new Array(n).fill(false);
        findAncestors(i, adjList, visited, ans[i]);
        ans[i].sort((a, b) => a - b);
    }
    return ans;
}
```
The algorithm works by iterating over all the given nodes and finding the ancestors of each node.
1. Create an adjacency list representation of the graph where the keys are the nodes and the values are lists of their parents.
2. For each node `i` in the graph, perform a Depth-First Search using a helper function `findAncestors()`, to explore all the ancestors by traversing the parent nodes.
3. During the search, maintain a `visited` array to prevent infinite loops and avoid visiting already visited nodes.
4. Append the ancestors of each node to a list and sort it in ascending order.
5. Return the list of ancestors for all nodes as a nested list.


# Max Difference You Can Get From Changing an Integer

- slug: max-difference-you-can-get-from-changing-an-integer
- difficulty: Medium

You are given an integer `num`. You will apply the following steps exactly **two** times:

*   Pick a digit `x (0 <= x <= 9)`.
*   Pick another digit `y (0 <= y <= 9)`. The digit `y` can be equal to `x`.
*   Replace all the occurrences of `x` in the decimal representation of `num` by `y`.
*   The new integer **cannot** have any leading zeros, also the new integer **cannot** be 0.

Let `a` and `b` be the results of applying the operations to `num` the first and second times, respectively.

Return _the max difference_ between `a` and `b`.

**Example 1:**

**Input:** num = 555
**Output:** 888
**Explanation:** The first time pick x = 5 and y = 9 and store the new integer in a.
The second time pick x = 5 and y = 1 and store the new integer in b.
We have now a = 999 and b = 111 and max difference = 888

**Example 2:**

**Input:** num = 9
**Output:** 8
**Explanation:** The first time pick x = 9 and y = 9 and store the new integer in a.
The second time pick x = 9 and y = 1 and store the new integer in b.
We have now a = 9 and b = 1 and max difference = 8

**Constraints:**

*   `1 <= num <= 10`8

## A solution in Java

```java
public int maxDiff(int num) {
    int a = -1, b = -1;
    String s = Integer.toString(num);
    for (char c : s.toCharArray()) {
        if (a == -1 && c != '9') {
            a = c - '0';
        }
        if (b == -1 && c > '1') {
            b = c - '0';
        }
        if (a != -1 && b != -1) {
            break;
        }
    }
    int result = 0;
    for (char c : s.toCharArray()) {
        if (c - '0' == a) {
            result = result * 10 + 9;
        } else if (c - '0' == b) {
            result = result * 10 + ((c == s.charAt(0)) ? 1 : 0);
        } else {
            result = result * 10 + c - '0';
        }
    }
    return result - num;
}
```
The algorithm first initializes two variables `a` and `b` with -1. Then, it iterates through the digits of the given integer `num` in the form of a string. It sets the values of `a` and `b` as follows:
- `a` is the first digit that is not 9. Changing this digit to 9 will result in the maximum possible integer.
- `b` is the first digit that is greater than 1. Changing this digit to 1 when it's the first digit, and to 0 otherwise, will result in the minimum possible integer.

After finding `a` and `b`, the algorithm iterates through the digits of `num` again and creates a new integer by replacing the digits of `num` with the corresponding processed digits. Finally, it returns the difference between the processed integer and the original one, which corresponds to the max difference between `a` and `b`.

## A solution in C++

```cpp
int maxDiff(int num) {
    int a = -1, b = -1;
    string s = to_string(num);
    for (char c : s) {
        if (a == -1 && c != '9') {
            a = c - '0';
        }
        if (b == -1 && c > '1') {
            b = c - '0';
        }
        if (a != -1 && b != -1) {
            break;
        }
    }
    for (char& c : s) {
        if (c - '0' == a) {
            c = '9';
        } else if (c - '0' == b) {
            c = (s.front() == c) ? '1' : '0';
        }
    }
    return stoi(s) - num;
}
```
The algorithm first initializes two variables `a` and `b` with -1. Then, it iterates through the digits of the given integer `num` in the form of a string. It sets the values of `a` and `b` as follows:
- `a` is the first digit that is not 9. Changing this digit to 9 will result in the maximum possible integer.
- `b` is the first digit that is greater than 1. Changing this digit to 1 when it's the first digit, and to 0 otherwise, will result in the minimum possible integer.

After finding `a` and `b`, the algorithm iterates through the digits of `num` again and creates a new integer by replacing the digits of `num` with the corresponding processed digits. Finally, it returns the difference between the processed integer and the original one, which corresponds to the max difference between `a` and `b`.

## A solution in Python

```python
def max_diff(num):
    a, b = -1, -1
    num_str = str(num)
    for c in num_str:
        if a == -1 and c != '9':
            a = int(c)
        if b == -1 and c > '1':
            b = int(c)
        if a != -1 and b != -1:
            break

    result = 0
    for c in num_str:
        if int(c) == a:
            result = result * 10 + 9
        elif int(c) == b:
            result = result * 10 + (1 if c == num_str[0] else 0)
        else:
            result = result * 10 + int(c)
    return result - num
```
The algorithm first initializes two variables `a` and `b` with -1. Then, it iterates through the digits of the given integer `num` in the form of a string. It sets the values of `a` and `b` as follows:
- `a` is the first digit that is not 9. Changing this digit to 9 will result in the maximum possible integer.
- `b` is the first digit that is greater than 1. Changing this digit to 1 when it's the first digit, and to 0 otherwise, will result in the minimum possible integer.

After finding `a` and `b`, the algorithm iterates through the digits of `num` again and creates a new integer by replacing the digits of `num` with the corresponding processed digits. Finally, it returns the difference between the processed integer and the original one, which corresponds to the max difference between `a` and `b`.

## A solution in Javascript

```javascript
function maxDiff(num) {
    let a = -1, b = -1;
    const numStr = num.toString();
    for (const c of numStr) {
        if (a === -1 && c !== '9') {
            a = parseInt(c);
        }
        if (b === -1 && c > '1') {
            b = parseInt(c);
        }
        if (a !== -1 && b !== -1) {
            break;
        }
    }
    let result = 0;
    for (const c of numStr) {
        if (parseInt(c) === a) {
            result = result * 10 + 9;
        } else if (parseInt(c) === b) {
            result = result * 10 + ((c === numStr[0]) ? 1 : 0);
        } else {
            result = result * 10 + parseInt(c);
        }
    }
    return result - num;
}
```
The algorithm first initializes two variables `a` and `b` with -1. Then, it iterates through the digits of the given integer `num` in the form of a string. It sets the values of `a` and `b` as follows:
- `a` is the first digit that is not 9. Changing this digit to 9 will result in the maximum possible integer.
- `b` is the first digit that is greater than 1. Changing this digit to 1 when it's the first digit, and to 0 otherwise, will result in the minimum possible integer.

After finding `a` and `b`, the algorithm iterates through the digits of `num` again and creates a new integer by replacing the digits of `num` with the corresponding processed digits. Finally, it returns the difference between the processed integer and the original one, which corresponds to the max difference between `a` and `b`.


# Check If a String Can Break Another String

- slug: check-if-a-string-can-break-another-string
- difficulty: Medium

Given two strings: `s1` and `s2` with the same size, check if some permutation of string `s1` can break some permutation of string `s2` or vice-versa. In other words `s2` can break `s1` or vice-versa.

A string `x` can break string `y` (both of size `n`) if `x[i] >= y[i]` (in alphabetical order) for all `i` between `0` and `n-1`.

**Example 1:**

**Input:** s1 =  "abc ", s2 =  "xya "
**Output:** true
**Explanation:**  "ayx " is a permutation of s2= "xya " which can break to string  "abc " which is a permutation of s1= "abc ".

**Example 2:**

**Input:** s1 =  "abe ", s2 =  "acd "
**Output:** false
**Explanation:** All permutations for s1= "abe " are:  "abe ",  "aeb ",  "bae ",  "bea ",  "eab " and  "eba " and all permutation for s2= "acd " are:  "acd ",  "adc ",  "cad ",  "cda ",  "dac " and  "dca ". However, there is not any permutation from s1 which can break some permutation from s2 and vice-versa.

**Example 3:**

**Input:** s1 =  "leetcodee ", s2 =  "interview "
**Output:** true

**Constraints:**

*   `s1.length == n`
*   `s2.length == n`
*   `1 <= n <= 10^5`
*   All strings consist of lowercase English letters.

## A solution in Java

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

public class Encrypter {
    private Map<Character, String> encryptMap;
    private Map<String, Character> decryptMap;
    private Set<String> dictionary;

    public Encrypter(char[] keys, String[] values, String[] dictionary) {
        encryptMap = new HashMap<>();
        decryptMap = new HashMap<>();
        this.dictionary = new HashSet<>();
        for (int i = 0; i < keys.length; i++) {
            encryptMap.put(keys[i], values[i]);
            decryptMap.put(values[i], keys[i]);
        }
        for (String word : dictionary) {
            this.dictionary.add(word);
        }
    }

    public String encrypt(String original) {
        StringBuilder res = new StringBuilder();
        for (char c : original.toCharArray()) {
            if (!encryptMap.containsKey(c)) {
                return "";
            }
            res.append(encryptMap.get(c));
        }
        return res.toString();
    }

    public String decrypt(String encrypted) {
        StringBuilder res = new StringBuilder();
        for (int i = 0; i < encrypted.length(); i += 2) {
            String temp = encrypted.substring(i, i + 2);
            if (!decryptMap.containsKey(temp)) {
                return "";
            }
            res.append(decryptMap.get(temp));
        }
        String decrypted = res.toString();
        if (!dictionary.contains(decrypted)) {
            return "";
        }
        return decrypted;
    }
}
```
The Encrypter class/constructor initializes three data structures:
1. `encrypt_map` to map the unique characters to their encrypted strings.
2. `decrypt_map` to map the encrypted strings back to their original characters.
3. `dictionary` to store the list of permitted original strings for decryption.

The `encrypt` function does the following:
- Iterates through the characters in the original string.
- Checks if the character is present in the `encrypt_map`. If not, it returns an empty string.
- Appends the encrypted value from the `encrypt_map` to the result.
- Returns the joined result as a string.

The `decrypt` function does the following:
- Iterates through the encrypted string in steps of 2 since all encrypted strings have a length of 2.
- Checks if the substring is present in the `decrypt_map`. If not, it returns an empty string.
- Appends the decrypted character from the `decrypt_map` to the result.
- Checks if the decrypted string is present in the `dictionary`. If not, it returns an empty string.
- Returns the decrypted string.

The overall algorithm for both encryption and decryption is O(n), where n is the length of the input string. The class provides a simple encryption and decryption process. The main limitation is that it can only handle unique characters, as stated in the problem description.

## A solution in C++

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

class Encrypter {
public:
    Encrypter(std::vector<char> keys, std::vector<std::string> values, std::vector<std::string> dictionary) {
        for (int i = 0; i < keys.size(); i++) {
            encrypt_map[keys[i]] = values[i];
            decrypt_map[values[i]] = keys[i];
        }
        for (const auto &word : dictionary) {
            this->dictionary.insert(word);
        }
    }

    std::string encrypt(const std::string &original) {
        std::string res = "";
        for (char c : original) {
            if (encrypt_map.find(c) == encrypt_map.end()) {
                return "";
            }
            res += encrypt_map[c];
        }
        return res;
    }

    std::string decrypt(const std::string &encrypted) {
        std::string res = "";
        for (int i = 0; i < encrypted.size(); i += 2) {
            std::string temp = encrypted.substr(i, 2);
            if (decrypt_map.find(temp) == decrypt_map.end()) {
                return "";
            }
            res += decrypt_map[temp];
        }
        if (dictionary.find(res) == dictionary.end()) {
            return "";
        }
        return res;
    }

private:
    std::unordered_map<char, std::string> encrypt_map;
    std::unordered_map<std::string, char> decrypt_map;
    std::unordered_set<std::string> dictionary;
};
```
The Encrypter class/constructor initializes three data structures:
1. `encrypt_map` to map the unique characters to their encrypted strings.
2. `decrypt_map` to map the encrypted strings back to their original characters.
3. `dictionary` to store the list of permitted original strings for decryption.

The `encrypt` function does the following:
- Iterates through the characters in the original string.
- Checks if the character is present in the `encrypt_map`. If not, it returns an empty string.
- Appends the encrypted value from the `encrypt_map` to the result.
- Returns the joined result as a string.

The `decrypt` function does the following:
- Iterates through the encrypted string in steps of 2 since all encrypted strings have a length of 2.
- Checks if the substring is present in the `decrypt_map`. If not, it returns an empty string.
- Appends the decrypted character from the `decrypt_map` to the result.
- Checks if the decrypted string is present in the `dictionary`. If not, it returns an empty string.
- Returns the decrypted string.

The overall algorithm for both encryption and decryption is O(n), where n is the length of the input string. The class provides a simple encryption and decryption process. The main limitation is that it can only handle unique characters, as stated in the problem description.

## A solution in Python

```python
class Encrypter:
    def __init__(self, keys, values, dictionary):
        self.encrypt_map = dict(zip(keys, values))
        self.decrypt_map = dict(zip(values, keys))
        self.dictionary = set(dictionary)

    def encrypt(self, original):
        result = []
        for c in original:
            if c not in self.encrypt_map:
                return ""
            result.append(self.encrypt_map[c])
        return "".join(result)

    def decrypt(self, encrypted):
        result = []
        for i in range(0, len(encrypted), 2):
            temp = encrypted[i:i+2]
            if temp not in self.decrypt_map:
                return ""
            result.append(self.decrypt_map[temp])

        decrypted = "".join(result)
        if decrypted not in self.dictionary:
            return ""
        return decrypted
```
The Encrypter class/constructor initializes three data structures:
1. `encrypt_map` to map the unique characters to their encrypted strings.
2. `decrypt_map` to map the encrypted strings back to their original characters.
3. `dictionary` to store the list of permitted original strings for decryption.

The `encrypt` function does the following:
- Iterates through the characters in the original string.
- Checks if the character is present in the `encrypt_map`. If not, it returns an empty string.
- Appends the encrypted value from the `encrypt_map` to the result.
- Returns the joined result as a string.

The `decrypt` function does the following:
- Iterates through the encrypted string in steps of 2 since all encrypted strings have a length of 2.
- Checks if the substring is present in the `decrypt_map`. If not, it returns an empty string.
- Appends the decrypted character from the `decrypt_map` to the result.
- Checks if the decrypted string is present in the `dictionary`. If not, it returns an empty string.
- Returns the decrypted string.

The overall algorithm for both encryption and decryption is O(n), where n is the length of the input string. The class provides a simple encryption and decryption process. The main limitation is that it can only handle unique characters, as stated in the problem description.

## A solution in Javascript

```javascript
class Encrypter {
    constructor(keys, values, dictionary) {
        this.encryptMap = new Map();
        this.decryptMap = new Map();
        this.dictionary = new Set(dictionary);
        for (let i = 0; i < keys.length; i++) {
            this.encryptMap.set(keys[i], values[i]);
            this.decryptMap.set(values[i], keys[i]);
        }
    }

    encrypt(original) {
        let res = [];
        for (const c of original) {
            if (!this.encryptMap.has(c)) {
                return "";
            }
            res.push(this.encryptMap.get(c));
        }
        return res.join('');
    }

    decrypt(encrypted) {
        let res = [];
        for (let i = 0; i < encrypted.length; i += 2) {
            const temp = encrypted.slice(i, i + 2);
            if (!this.decryptMap.has(temp)) {
                return "";
            }
            res.push(this.decryptMap.get(temp));
        }
        const decrypted = res.join('');
        if (!this.dictionary.has(decrypted)) {
            return "";
        }
        return decrypted;
    }
}
```
The Encrypter class/constructor initializes three data structures:
1. `encrypt_map` to map the unique characters to their encrypted strings.
2. `decrypt_map` to map the encrypted strings back to their original characters.
3. `dictionary` to store the list of permitted original strings for decryption.

The `encrypt` function does the following:
- Iterates through the characters in the original string.
- Checks if the character is present in the `encrypt_map`. If not, it returns an empty string.
- Appends the encrypted value from the `encrypt_map` to the result.
- Returns the joined result as a string.

The `decrypt` function does the following:
- Iterates through the encrypted string in steps of 2 since all encrypted strings have a length of 2.
- Checks if the substring is present in the `decrypt_map`. If not, it returns an empty string.
- Appends the decrypted character from the `decrypt_map` to the result.
- Checks if the decrypted string is present in the `dictionary`. If not, it returns an empty string.
- Returns the decrypted string.

The overall algorithm for both encryption and decryption is O(n), where n is the length of the input string. The class provides a simple encryption and decryption process. The main limitation is that it can only handle unique characters, as stated in the problem description.


# Number of Ways to Wear Different Hats to Each Other

- slug: number-of-ways-to-wear-different-hats-to-each-other
- difficulty: Hard

There are `n` people and `40` types of hats labeled from `1` to `40`.

Given a 2D integer array `hats`, where `hats[i]` is a list of all hats preferred by the `ith` person.

Return _the number of ways that the `n` people wear different hats to each other_.

Since the answer may be too large, return it modulo `109 + 7`.

**Example 1:**

**Input:** hats = \[\[3,4\],\[4,5\],\[5\]\]
**Output:** 1
**Explanation:** There is only one way to choose hats given the conditions.
First person choose hat 3, Second person choose hat 4 and last one hat 5.

**Example 2:**

**Input:** hats = \[\[3,5,1\],\[3,5\]\]
**Output:** 4
**Explanation:** There are 4 ways to choose hats:
(3,5), (5,3), (1,3) and (1,5)

**Example 3:**

**Input:** hats = \[\[1,2,3,4\],\[1,2,3,4\],\[1,2,3,4\],\[1,2,3,4\]\]
**Output:** 24
**Explanation:** Each person can choose hats labeled from 1 to 4.
Number of Permutations of (1,2,3,4) = 24.

**Constraints:**

*   `n == hats.length`
*   `1 <= n <= 10`
*   `1 <= hats[i].length <= 40`
*   `1 <= hats[i][j] <= 40`
*   `hats[i]` contains a list of **unique** integers.

## A solution in Java

```java
public class Solution {
    public String freqAlphabets(String s) {
        StringBuilder result = new StringBuilder();
        int i = 0;
        while (i < s.length()) {
            if (i + 2 < s.length() && s.charAt(i + 2) == '#') {
                result.append((char) ('a' + (s.charAt(i) - '0') * 10 + (s.charAt(i + 1) - '0') - 10));
                i += 3;
            } else {
                result.append((char) ('a' + s.charAt(i) - '1'));
                i++;
            }
        }
        return result.toString();
    }
}
```
The algorithm iterates through the given input string `s`. When it encounters a '#' symbol, it means the 2 characters before the '#' form a two-digit number that maps to a character. We take that 2-digit number, convert it to an English lowercase character using ASCII by adding the number to the ASCII code of 'a', and append the character to the result string. If there is no '#' symbol, we simply consider the single-digit number and map it to a character. Finally, we return the mapped string.

## A solution in C++

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

string freqAlphabets(string s) {
    string result = "";
    for (int i = 0; i < s.length(); i++) {
        if (i + 2 < s.length() && s[i + 2] == '#') {
            result += ('a' + (s[i] - '0') * 10 + (s[i + 1] - '0') - 10);
            i += 2;
        } else {
            result += ('a' + s[i] - '1');
        }
    }
    return result;
}
```
The algorithm iterates through the given input string `s`. When it encounters a '#' symbol, it means the 2 characters before the '#' form a two-digit number that maps to a character. We take that 2-digit number, convert it to an English lowercase character using ASCII by adding the number to the ASCII code of 'a', and append the character to the result string. If there is no '#' symbol, we simply consider the single-digit number and map it to a character. Finally, we return the mapped string.

## A solution in Python

```python
def freqAlphabets(s):
    result = []
    i = 0
    while i < len(s):
        if i + 2 < len(s) and s[i + 2] == '#':
            result.append(chr(ord('a') + int(s[i:i + 2]) - 1))
            i += 3
        else:
            result.append(chr(ord('a') + int(s[i]) - 1))
            i += 1
    return ''.join(result)
```
The algorithm iterates through the given input string `s`. When it encounters a '#' symbol, it means the 2 characters before the '#' form a two-digit number that maps to a character. We take that 2-digit number, convert it to an English lowercase character using ASCII by adding the number to the ASCII code of 'a', and append the character to the result string. If there is no '#' symbol, we simply consider the single-digit number and map it to a character. Finally, we return the mapped string.

## A solution in Javascript

```javascript
function freqAlphabets(s) {
    let result = [];
    for (let i = 0; i < s.length;) {
        if (i + 2 < s.length && s[i + 2] === "#") {
            result.push(String.fromCharCode("a".charCodeAt(0) + parseInt(s.substring(i, i + 2)) - 1));
            i += 3;
        } else {
            result.push(String.fromCharCode("a".charCodeAt(0) + parseInt(s[i]) - 1));
            i++;
        }
    }
    return result.join('');
}
```
The algorithm iterates through the given input string `s`. When it encounters a '#' symbol, it means the 2 characters before the '#' form a two-digit number that maps to a character. We take that 2-digit number, convert it to an English lowercase character using ASCII by adding the number to the ASCII code of 'a', and append the character to the result string. If there is no '#' symbol, we simply consider the single-digit number and map it to a character. Finally, we return the mapped string.


# Destination City

- slug: destination-city
- difficulty: Easy

You are given the array `paths`, where `paths[i] = [cityAi, cityBi]` means there exists a direct path going from `cityAi` to `cityBi`. _Return the destination city, that is, the city without any path outgoing to another city._

It is guaranteed that the graph of paths forms a line without any loop, therefore, there will be exactly one destination city.

**Example 1:**

**Input:** paths = \[\[ "London ", "New York "\],\[ "New York ", "Lima "\],\[ "Lima ", "Sao Paulo "\]\]
**Output:**  "Sao Paulo "
**Explanation:** Starting at  "London " city you will reach  "Sao Paulo " city which is the destination city. Your trip consist of:  "London " ->  "New York " ->  "Lima " ->  "Sao Paulo ".

**Example 2:**

**Input:** paths = \[\[ "B ", "C "\],\[ "D ", "B "\],\[ "C ", "A "\]\]
**Output:**  "A "
**Explanation:** All possible trips are:
 "D " ->  "B " ->  "C " ->  "A ".
 "B " ->  "C " ->  "A ".
 "C " ->  "A ".
 "A ".
Clearly the destination city is  "A ".

**Example 3:**

**Input:** paths = \[\[ "A ", "Z "\]\]
**Output:**  "Z "

**Constraints:**

*   `1 <= paths.length <= 100`
*   `paths[i].length == 2`
*   `1 <= cityAi.length, cityBi.length <= 10`
*   `cityAi != cityBi`
*   All strings consist of lowercase and uppercase English letters and the space character.

## A solution in Java

```java
import java.util.*;

public List<String> watchedVideosByFriends(List<List<String>> watchedVideos, int[][] friends, int id, int level) {
    Set<Integer> visited = new HashSet<>();
    Queue<int[]> q = new LinkedList<>();
    Map<String, Integer> videoFreq = new HashMap<>();

    q.offer(new int[]{id, 0});
    visited.add(id);

    while (!q.isEmpty()) {
        int[] pair = q.poll();
        int currentId = pair[0];
        int currentLevel = pair[1];

        if (currentLevel == level) {
            for (String video : watchedVideos.get(currentId)) {
                videoFreq.put(video, videoFreq.getOrDefault(video, 0) + 1);
            }
        } else if (currentLevel < level) {
            for (int friendId : friends[currentId]) {
                if (!visited.contains(friendId)) {
                    visited.add(friendId);
                    q.offer(new int[]{friendId, currentLevel + 1});
                }
            }
        }
    }

    List<String> result = new ArrayList<>(videoFreq.keySet());

    result.sort((a, b) -> {
        if (videoFreq.get(a).equals(videoFreq.get(b))) {
            return a.compareTo(b);
        } else {
            return videoFreq.get(a) - videoFreq.get(b);
        }
    });

    return result;
}
```
The algorithm works as follows:
1. Initialize a visited set to keep track of the visited person ids, and a queue, which stores pairs containing the person id and the level or search depth.
2. Push the given id and level 0 onto the queue and mark the id visited.
3. While there are still unprocessed items in the queue, check the current level of the person in the queue.
  a) If the current level is equal to the given level, increment the count of each video watched by this person in a frequency map.
  b) If the current level is less than the given level, iterate through the friends of the current person and push those friends' ids in the queue with the incremented level if they haven't been visited yet, and mark them visited.
4. Create a result list from the keys in the frequency map.
5. Sort the result list based on the frequency of the videos and their names.
6. Return the sorted result list.

This algorithm has a breadth-first search (BFS) traversal through the connections, which helps in finding the shortest path.

## A solution in C++

```cpp
#include <vector>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <algorithm>
#include <string>

using namespace std;

vector<string> watchedVideosByFriends(vector<vector<string>>& watchedVideos, vector<vector<int>>& friends, int id, int level) {
    unordered_set<int> visited;
    queue<pair<int, int>> q;
    unordered_map<string, int> video_freq;

    q.push({id, 0});
    visited.insert(id);

    while (!q.empty()) {
        int current_id = q.front().first;
        int current_level = q.front().second;
        q.pop();

        if (current_level == level) {
            for (const string& video : watchedVideos[current_id]) {
                video_freq[video]++;
            }
        } else if (current_level < level) {
            for (int friend_id : friends[current_id]) {
                if (visited.find(friend_id) == visited.end()) {
                    visited.insert(friend_id);
                    q.push({friend_id, current_level + 1});
                }
            }
        }
    }

    vector<string> result;
    for (const auto& p : video_freq) {
        result.push_back(p.first);
    }

    sort(result.begin(), result.end(), [&video_freq](const string& a, const string& b) {
        if (video_freq[a] == video_freq[b]) {
            return a < b;
        } else {
            return video_freq[a] < video_freq[b];
        }
    });

    return result;
}
```
The algorithm works as follows:
1. Initialize a visited set to keep track of the visited person ids, and a queue, which stores pairs containing the person id and the level or search depth.
2. Push the given id and level 0 onto the queue and mark the id visited.
3. While there are still unprocessed items in the queue, check the current level of the person in the queue.
  a) If the current level is equal to the given level, increment the count of each video watched by this person in a frequency map.
  b) If the current level is less than the given level, iterate through the friends of the current person and push those friends' ids in the queue with the incremented level if they haven't been visited yet, and mark them visited.
4. Create a result list from the keys in the frequency map.
5. Sort the result list based on the frequency of the videos and their names.
6. Return the sorted result list.

This algorithm has a breadth-first search (BFS) traversal through the connections, which helps in finding the shortest path.

## A solution in Python

```python
from collections import deque
from collections import defaultdict

def watched_videos_by_friends(watched_videos, friends, id, level):
    visited = set()
    q = deque([(id, 0)])
    video_freq = defaultdict(int)

    while q:
        current_id, current_level = q.popleft()

        if current_level == level:
            for video in watched_videos[current_id]:
                video_freq[video] += 1
        elif current_level < level:
            for friend_id in friends[current_id]:
                if friend_id not in visited:
                    visited.add(friend_id)
                    q.append((friend_id, current_level + 1))

    result = sorted(video_freq.keys(), key=lambda x: (video_freq[x], x))

    return result
```
The algorithm works as follows:
1. Initialize a visited set to keep track of the visited person ids, and a queue, which stores pairs containing the person id and the level or search depth.
2. Push the given id and level 0 onto the queue and mark the id visited.
3. While there are still unprocessed items in the queue, check the current level of the person in the queue.
  a) If the current level is equal to the given level, increment the count of each video watched by this person in a frequency map.
  b) If the current level is less than the given level, iterate through the friends of the current person and push those friends' ids in the queue with the incremented level if they haven't been visited yet, and mark them visited.
4. Create a result list from the keys in the frequency map.
5. Sort the result list based on the frequency of the videos and their names.
6. Return the sorted result list.

This algorithm has a breadth-first search (BFS) traversal through the connections, which helps in finding the shortest path.

## A solution in Javascript

```javascript
function watchedVideosByFriends(watchedVideos, friends, id, level) {
    const visited = new Set();
    const q = [{ id, level: 0 }];
    const videoFreq = new Map();

    while (q.length !== 0) {
        const { id: currentId, level: currentLevel } = q.shift();

        if (currentLevel === level) {
            for (const video of watchedVideos[currentId]) {
                videoFreq.set(video, (videoFreq.get(video) || 0) + 1);
            }
        } else if (currentLevel < level) {
            for (const friendId of friends[currentId]) {
                if (!visited.has(friendId)) {
                    visited.add(friendId);
                    q.push({ id: friendId, level: currentLevel + 1 });
                }
            }
        }
    }

    const result = Array.from(videoFreq.keys());
    result.sort((a, b) => {
        if (videoFreq.get(a) === videoFreq.get(b)) {
            return a.localeCompare(b);
        } else {
            return videoFreq.get(a) - videoFreq.get(b);
         }
    });

    return result;
}
```
The algorithm works as follows:
1. Initialize a visited set to keep track of the visited person ids, and a queue, which stores pairs containing the person id and the level or search depth.
2. Push the given id and level 0 onto the queue and mark the id visited.
3. While there are still unprocessed items in the queue, check the current level of the person in the queue.
  a) If the current level is equal to the given level, increment the count of each video watched by this person in a frequency map.
  b) If the current level is less than the given level, iterate through the friends of the current person and push those friends' ids in the queue with the incremented level if they haven't been visited yet, and mark them visited.
4. Create a result list from the keys in the frequency map.
5. Sort the result list based on the frequency of the videos and their names.
6. Return the sorted result list.

This algorithm has a breadth-first search (BFS) traversal through the connections, which helps in finding the shortest path.


# Check If All 1's Are at Least Length K Places Away

- slug: check-if-all-1s-are-at-least-length-k-places-away
- difficulty: Easy

Given an binary array `nums` and an integer `k`, return `true` _if all_ `1`_'s are at least_ `k` _places away from each other, otherwise return_ `false`.

**Example 1:**

**Input:** nums = \[1,0,0,0,1,0,0,1\], k = 2
**Output:** true
**Explanation:** Each of the 1s are at least 2 places away from each other.

**Example 2:**

**Input:** nums = \[1,0,0,1,0,1\], k = 2
**Output:** false
**Explanation:** The second 1 and third 1 are only one apart from each other.

**Constraints:**

*   `1 <= nums.length <= 105`
*   `0 <= k <= nums.length`
*   `nums[i]` is `0` or `1`

## A solution in Java

```java
int minStepsToMakePalindrome(String s) {
    int n = s.length();
    int[][] dp = new int[n][n];

    for (int i = n - 2; i >= 0; i--) {
        for (int j = i + 1; j < n; j++) {
            if (s.charAt(i) == s.charAt(j)) {
                dp[i][j] = dp[i + 1][j - 1];
            } else {
                dp[i][j] = 1 + Math.min(dp[i + 1][j], dp[i][j - 1]);
            }
        }
    }

    return dp[0][n - 1];
}
```
We use dynamic programming to find the minimum number of steps required to make a string palindrome. The `dp[i][j]` element of the 2D `dp` array represents the minimum number of steps required to make a palindrome from substring `s[i..j]`. We iterate through the string in reverse order, and for each pair of characters, if the characters are equal, we update the `dp[i][j]` value using the `dp[i+1][j-1]`. If they are not equal, we update the `dp[i][j]` using the minimum value between `dp[i+1][j]` and `dp[i][j-1]`, adding 1 to it. In the end, we return the value at `dp[0][n-1]`, which represents the minimum steps required to make the whole string palindrome.

## A solution in C++

```cpp
int minStepsToMakePalindrome(std::string s) {
    int n = s.size();
    std::vector<std::vector<int>> dp(n, std::vector<int>(n, 0));

    for (int i = n - 2; i >= 0; i--) {
        for (int j = i + 1; j < n; j++) {
            if (s[i] == s[j]) {
                dp[i][j] = dp[i + 1][j - 1];
            } else {
                dp[i][j] = 1 + std::min(dp[i + 1][j], dp[i][j - 1]);
            }
        }
    }

    return dp[0][n - 1];
}
```
We use dynamic programming to find the minimum number of steps required to make a string palindrome. The `dp[i][j]` element of the 2D `dp` array represents the minimum number of steps required to make a palindrome from substring `s[i..j]`. We iterate through the string in reverse order, and for each pair of characters, if the characters are equal, we update the `dp[i][j]` value using the `dp[i+1][j-1]`. If they are not equal, we update the `dp[i][j]` using the minimum value between `dp[i+1][j]` and `dp[i][j-1]`, adding 1 to it. In the end, we return the value at `dp[0][n-1]`, which represents the minimum steps required to make the whole string palindrome.

## A solution in Python

```python
def min_steps_to_make_palindrome(s):
    n = len(s)
    dp = [[0] * n for _ in range(n)]

    for i in range(n - 2, -1, -1):
        for j in range(i + 1, n):
            if s[i] == s[j]:
                dp[i][j] = dp[i + 1][j - 1]
            else:
                dp[i][j] = 1 + min(dp[i + 1][j], dp[i][j - 1])

    return dp[0][n - 1]
```
We use dynamic programming to find the minimum number of steps required to make a string palindrome. The `dp[i][j]` element of the 2D `dp` array represents the minimum number of steps required to make a palindrome from substring `s[i..j]`. We iterate through the string in reverse order, and for each pair of characters, if the characters are equal, we update the `dp[i][j]` value using the `dp[i+1][j-1]`. If they are not equal, we update the `dp[i][j]` using the minimum value between `dp[i+1][j]` and `dp[i][j-1]`, adding 1 to it. In the end, we return the value at `dp[0][n-1]`, which represents the minimum steps required to make the whole string palindrome.

## A solution in Javascript

```javascript
function minStepsToMakePalindrome(s) {
    const n = s.length;
    const dp = Array.from({ length: n }, () => Array(n).fill(0));

    for (let i = n - 2; i >= 0; i--) {
        for (let j = i + 1; j < n; j++) {
            if (s[i] === s[j]) {
                dp[i][j] = dp[i + 1][j - 1];
            } else {
                dp[i][j] = 1 + Math.min(dp[i + 1][j], dp[i][j - 1]);
            }
        }
    }

    return dp[0][n - 1];
}
```
We use dynamic programming to find the minimum number of steps required to make a string palindrome. The `dp[i][j]` element of the 2D `dp` array represents the minimum number of steps required to make a palindrome from substring `s[i..j]`. We iterate through the string in reverse order, and for each pair of characters, if the characters are equal, we update the `dp[i][j]` value using the `dp[i+1][j-1]`. If they are not equal, we update the `dp[i][j]` using the minimum value between `dp[i+1][j]` and `dp[i][j-1]`, adding 1 to it. In the end, we return the value at `dp[0][n-1]`, which represents the minimum steps required to make the whole string palindrome.


# Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit

- slug: longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit
- difficulty: Medium

Given an array of integers `nums` and an integer `limit`, return the size of the longest **non-empty** subarray such that the absolute difference between any two elements of this subarray is less than or equal to `limit`_._

**Example 1:**

**Input:** nums = \[8,2,4,7\], limit = 4
**Output:** 2
**Explanation:** All subarrays are:
\[8\] with maximum absolute diff |8-8| = 0 <= 4.
\[8,2\] with maximum absolute diff |8-2| = 6 > 4.
\[8,2,4\] with maximum absolute diff |8-2| = 6 > 4.
\[8,2,4,7\] with maximum absolute diff |8-2| = 6 > 4.
\[2\] with maximum absolute diff |2-2| = 0 <= 4.
\[2,4\] with maximum absolute diff |2-4| = 2 <= 4.
\[2,4,7\] with maximum absolute diff |2-7| = 5 > 4.
\[4\] with maximum absolute diff |4-4| = 0 <= 4.
\[4,7\] with maximum absolute diff |4-7| = 3 <= 4.
\[7\] with maximum absolute diff |7-7| = 0 <= 4.
Therefore, the size of the longest subarray is 2.

**Example 2:**

**Input:** nums = \[10,1,2,4,7,2\], limit = 5
**Output:** 4
**Explanation:** The subarray \[2,4,7,2\] is the longest since the maximum absolute diff is |2-7| = 5 <= 5.

**Example 3:**

**Input:** nums = \[4,2,2,2,4,4,2,2\], limit = 0
**Output:** 3

**Constraints:**

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

## A solution in Java

```java
import java.util.ArrayDeque;
import java.util.Deque;

public int longestSubarray(int[] nums, int limit) {
    Deque<Integer> maxDeque = new ArrayDeque<>();
    Deque<Integer> minDeque = new ArrayDeque<>();
    int left = 0, right = 0, longest = 0;
    while (right < nums.length) {
        while (!maxDeque.isEmpty() && nums[right] > maxDeque.peekLast()) maxDeque.pollLast();
        while (!minDeque.isEmpty() && nums[right] < minDeque.peekLast()) minDeque.pollLast();

        maxDeque.offerLast(nums[right]);
        minDeque.offerLast(nums[right]);

        while (maxDeque.peekFirst() - minDeque.peekFirst() > limit) {
            if (nums[left] == maxDeque.peekFirst()) maxDeque.pollFirst();
            if (nums[left] == minDeque.peekFirst()) minDeque.pollFirst();
            left++;
        }

        longest = Math.max(longest, right - left + 1);
        right++;
    }
    return longest;
}
```
The idea here is to use two double-ended queues (deques) to keep track of the maximum and minimum values in the current subarray, as well as two pointers (left and right) to keep track of the subarray itself. We move the right pointer the array by incrementing it and add elements to the deques while maintaining the order (descending for max_deque and ascending for min_deque). If the difference between the maximum and minimum values in the subarray exceeds the limit, we move the left pointer forward to find another subarray. We then update the longest subarray size as we traverse the array.

This approach is called sliding window and has an O(N) time complexity since we move both pointers exactly once throughout the array.

## A solution in C++

```cpp
#include <deque>
int longestSubarray(vector<int>& nums, int limit) {
    deque<int> max_deque, min_deque;
    int left = 0, right = 0, longest = 0;
    while (right < nums.size()) {
        while (!max_deque.empty() && nums[right] > max_deque.back()) max_deque.pop_back();
        while (!min_deque.empty() && nums[right] < min_deque.back()) min_deque.pop_back();

        max_deque.push_back(nums[right]);
        min_deque.push_back(nums[right]);

        while (max_deque.front() - min_deque.front() > limit) {
            if (max_deque.front() == nums[left]) max_deque.pop_front();
            if (min_deque.front() == nums[left]) min_deque.pop_front();
            left++;
        }

        longest = max(longest, right - left + 1);
        right++;
    }
    return longest;
}
```
The idea here is to use two double-ended queues (deques) to keep track of the maximum and minimum values in the current subarray, as well as two pointers (left and right) to keep track of the subarray itself. We move the right pointer the array by incrementing it and add elements to the deques while maintaining the order (descending for max_deque and ascending for min_deque). If the difference between the maximum and minimum values in the subarray exceeds the limit, we move the left pointer forward to find another subarray. We then update the longest subarray size as we traverse the array.

This approach is called sliding window and has an O(N) time complexity since we move both pointers exactly once throughout the array.

## A solution in Python

```python
from collections import deque
def longestSubarray(nums, limit):
    max_deque = deque()
    min_deque = deque()
    left, right, longest = 0, 0, 0

    while right < len(nums):
        while max_deque and nums[right] > max_deque[-1]: max_deque.pop()
        while min_deque and nums[right] < min_deque[-1]: min_deque.pop()

        max_deque.append(nums[right])
        min_deque.append(nums[right])

        while max_deque[0] - min_deque[0] > limit:
            if max_deque[0] == nums[left]: max_deque.popleft()
            if min_deque[0] == nums[left]: min_deque.popleft()
            left += 1

        longest = max(longest, right - left + 1)
        right += 1

    return longest
```
The idea here is to use two double-ended queues (deques) to keep track of the maximum and minimum values in the current subarray, as well as two pointers (left and right) to keep track of the subarray itself. We move the right pointer the array by incrementing it and add elements to the deques while maintaining the order (descending for max_deque and ascending for min_deque). If the difference between the maximum and minimum values in the subarray exceeds the limit, we move the left pointer forward to find another subarray. We then update the longest subarray size as we traverse the array.

This approach is called sliding window and has an O(N) time complexity since we move both pointers exactly once throughout the array.

## A solution in Javascript

```javascript
function longestSubarray(nums, limit) {
    const maxDeque = [], minDeque = [];
    let left = 0, right = 0, longest = 0;

    while (right < nums.length) {
        while (maxDeque.length && nums[right] > maxDeque[maxDeque.length - 1]) maxDeque.pop();
        while (minDeque.length && nums[right] < minDeque[minDeque.length - 1]) minDeque.pop();

        maxDeque.push(nums[right]);
        minDeque.push(nums[right]);

        while (maxDeque[0] - minDeque[0] > limit) {
            if (maxDeque[0] === nums[left]) maxDeque.shift();
            if (minDeque[0] === nums[left]) minDeque.shift();
            left++;
        }

        longest = Math.max(longest, right - left + 1);
        right++;
    }
    return longest;
}
```
The idea here is to use two double-ended queues (deques) to keep track of the maximum and minimum values in the current subarray, as well as two pointers (left and right) to keep track of the subarray itself. We move the right pointer the array by incrementing it and add elements to the deques while maintaining the order (descending for max_deque and ascending for min_deque). If the difference between the maximum and minimum values in the subarray exceeds the limit, we move the left pointer forward to find another subarray. We then update the longest subarray size as we traverse the array.

This approach is called sliding window and has an O(N) time complexity since we move both pointers exactly once throughout the array.