# Next Greater Element III

- slug: next-greater-element-iii
- difficulty: Medium

Given a positive integer `n`, find _the smallest integer which has exactly the same digits existing in the integer_ `n` _and is greater in value than_ `n`. If no such positive integer exists, return `-1`.

**Note** that the returned integer should fit in **32-bit integer**, if there is a valid answer but it does not fit in **32-bit integer**, return `-1`.

**Example 1:**

**Input:** n = 12
**Output:** 21

**Example 2:**

**Input:** n = 21
**Output:** -1

**Constraints:**

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

## A solution in Java

```java
import java.util.Arrays;

public class Main {
    public int nextGreaterElement(int n) {
        char[] number = String.valueOf(n).toCharArray();
        int i, j;
        for (i = number.length - 1; i > 0; i--) {
            if (number[i - 1] < number[i]) {
                break;
            }
        }

        if (i == 0) {
            return -1;
        }

        int x = number[i - 1], smallest = i;
        for (j = i + 1; j < number.length; j++) {
            if (number[j] > x && number[j] < number[smallest]) {
                smallest = j;
            }
        }

        char temp = number[i - 1];
        number[i - 1] = number[smallest];
        number[smallest] = temp;

        Arrays.sort(number, i, number.length);

        long result = Long.parseLong(new String(number));

        return (result <= Integer.MAX_VALUE) ? (int) result : -1;
    }
}
```
1. Convert input integer n to string/array of characters.
2. Find the rightmost character such that when swapped with a character greater than it, the number increases. If no such character exists, return -1.
3. Swap the character found with the smallest character to its right that is greater than it.
4. Sort the portion of the array to the right of the swapped character in non-descending order.
5. Convert the modified array back to an integer and check if it fits in 32-bit integer. If yes, return the integer, otherwise return -1.

## A solution in C++

```cpp
#include <bits/stdc++.h>
using namespace std;

int32_t nextGreaterElement(int n) {
    string num = to_string(n);
    if (next_permutation(num.begin(), num.end())) {
        long long result = stoll(num);
        if (result <= INT32_MAX) {
            return result;
        }
    }
    return -1;
}
```
1. Convert input integer n to string/array of characters.
2. Find the rightmost character such that when swapped with a character greater than it, the number increases. If no such character exists, return -1.
3. Swap the character found with the smallest character to its right that is greater than it.
4. Sort the portion of the array to the right of the swapped character in non-descending order.
5. Convert the modified array back to an integer and check if it fits in 32-bit integer. If yes, return the integer, otherwise return -1.

## A solution in Python

```python
from itertools import permutations

def nextGreaterElement(n: int) -> int:
    num_str = str(n)
    num_permutations = sorted(set(int("".join(p)) for p in permutations(num_str)))
    index = num_permutations.index(n)
    if index + 1 < len(num_permutations) and num_permutations[index + 1] <= 2**31 - 1:
        return num_permutations[index + 1]
    return -1
```
1. Convert input integer n to string/array of characters.
2. Find the rightmost character such that when swapped with a character greater than it, the number increases. If no such character exists, return -1.
3. Swap the character found with the smallest character to its right that is greater than it.
4. Sort the portion of the array to the right of the swapped character in non-descending order.
5. Convert the modified array back to an integer and check if it fits in 32-bit integer. If yes, return the integer, otherwise return -1.

## A solution in Javascript

```javascript
function nextGreaterElement(n) {
    const numStr = n.toString();
    let numArr = numStr.split('');
    let i, j;

    for (i = numArr.length - 1; i > 0; i--) {
        if (+numArr[i - 1] < +numArr[i]) break;
    }

    if (i === 0) return -1;

    let x = +numArr[i - 1], smallest = i;
    for (j = i + 1; j < numArr.length; j++) {
        if (+numArr[j] > x && +numArr[j] < +numArr[smallest]) {
            smallest = j;
        }
    }

    [numArr[smallest], numArr[i - 1]] = [numArr[i - 1], numArr[smallest]];

    numArr = [...numArr.slice(0, i), ...numArr.slice(i).sort()];

    const result = parseInt(numArr.join(''), 10);

    return (result <= Math.pow(2, 31) - 1) ? result : -1;
}
```
1. Convert input integer n to string/array of characters.
2. Find the rightmost character such that when swapped with a character greater than it, the number increases. If no such character exists, return -1.
3. Swap the character found with the smallest character to its right that is greater than it.
4. Sort the portion of the array to the right of the swapped character in non-descending order.
5. Convert the modified array back to an integer and check if it fits in 32-bit integer. If yes, return the integer, otherwise return -1.


# Reverse Words in a String III

- slug: reverse-words-in-a-string-iii
- difficulty: Easy

Given a string `s`, reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order.

**Example 1:**

**Input:** s = "Let's take LeetCode contest"
**Output:** "s'teL ekat edoCteeL tsetnoc"

**Example 2:**

**Input:** s = "God Ding"
**Output:** "doG gniD"

**Constraints:**

*   `1 <= s.length <= 5 * 104`
*   `s` contains printable **ASCII** characters.
*   `s` does not contain any leading or trailing spaces.
*   There is **at least one** word in `s`.
*   All the words in `s` are separated by a single space.

## A solution in Java

```java
import java.util.StringJoiner;

public String reverseWordsInString(String s) {
    String[] words = s.split(" ");
    for (int i = 0; i < words.length; i++) {
        words[i] = new StringBuilder(words[i]).reverse().toString();
    }
    return String.join(" ", words);
}
```
The algorithm first splits the input string `s` into words based on whitespace. Then, for each word, it reverses the order of characters and appends it to the output. Finally, the reversed words are joined with whitespace and returned as the result.

In each language implementation:
- C++: The algorithm uses `istringstream` to split the string into words and `ostringstream` to create the output string.
- Java: The algorithm splits the string using `split`, reverses each word using `StringBuilder` and then `String.join` to join the words with a space delimiter.
- Python: The algorithm uses a list comprehension to reverse the words in the input string and `join` to concatenate them.
- JavaScript: The algorithm uses `split`, `map`, and `join` operations on the input string to reverse each word and concatenate them.

## A solution in C++

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

std::string reverseWordsInString(const std::string& s) {
    std::istringstream iss(s);
    std::ostringstream oss;
    std::string word;
    while (iss >> word) {
        std::reverse(word.begin(), word.end());
        oss << word << ' ';
    }
    std::string result = oss.str();
    if (!result.empty()) result.pop_back();
    return result;
}
```
The algorithm first splits the input string `s` into words based on whitespace. Then, for each word, it reverses the order of characters and appends it to the output. Finally, the reversed words are joined with whitespace and returned as the result.

In each language implementation:
- C++: The algorithm uses `istringstream` to split the string into words and `ostringstream` to create the output string.
- Java: The algorithm splits the string using `split`, reverses each word using `StringBuilder` and then `String.join` to join the words with a space delimiter.
- Python: The algorithm uses a list comprehension to reverse the words in the input string and `join` to concatenate them.
- JavaScript: The algorithm uses `split`, `map`, and `join` operations on the input string to reverse each word and concatenate them.

## A solution in Python

```python
def reverse_words_in_string(s: str) -> str:
    return " ".join(word[::-1] for word in s.split(" "))
```
The algorithm first splits the input string `s` into words based on whitespace. Then, for each word, it reverses the order of characters and appends it to the output. Finally, the reversed words are joined with whitespace and returned as the result.

In each language implementation:
- C++: The algorithm uses `istringstream` to split the string into words and `ostringstream` to create the output string.
- Java: The algorithm splits the string using `split`, reverses each word using `StringBuilder` and then `String.join` to join the words with a space delimiter.
- Python: The algorithm uses a list comprehension to reverse the words in the input string and `join` to concatenate them.
- JavaScript: The algorithm uses `split`, `map`, and `join` operations on the input string to reverse each word and concatenate them.

## A solution in Javascript

```javascript
function reverseWordsInString(s) {
    return s.split(' ').map(word => word.split('').reverse().join('')).join(' ');
}
```
The algorithm first splits the input string `s` into words based on whitespace. Then, for each word, it reverses the order of characters and appends it to the output. Finally, the reversed words are joined with whitespace and returned as the result.

In each language implementation:
- C++: The algorithm uses `istringstream` to split the string into words and `ostringstream` to create the output string.
- Java: The algorithm splits the string using `split`, reverses each word using `StringBuilder` and then `String.join` to join the words with a space delimiter.
- Python: The algorithm uses a list comprehension to reverse the words in the input string and `join` to concatenate them.
- JavaScript: The algorithm uses `split`, `map`, and `join` operations on the input string to reverse each word and concatenate them.


# Logical OR of Two Binary Grids Represented as Quad-Trees

- slug: logical-or-of-two-binary-grids-represented-as-quad-trees
- difficulty: Medium

A Binary Matrix is a matrix in which all the elements are either **0** or **1**.

Given `quadTree1` and `quadTree2`. `quadTree1` represents a `n * n` binary matrix and `quadTree2` represents another `n * n` binary matrix.

Return _a Quad-Tree_ representing the `n * n` binary matrix which is the result of **logical bitwise OR** of the two binary matrixes represented by `quadTree1` and `quadTree2`.

Notice that you can assign the value of a node to **True** or **False** when `isLeaf` is **False**, and both are **accepted** in the answer.

A Quad-Tree is a tree data structure in which each internal node has exactly four children. Besides, each node has two attributes:

*   `val`: True if the node represents a grid of 1's or False if the node represents a grid of 0's.
*   `isLeaf`: True if the node is leaf node on the tree or False if the node has the four children.

class Node {
    public boolean val;
    public boolean isLeaf;
    public Node topLeft;
    public Node topRight;
    public Node bottomLeft;
    public Node bottomRight;
}

We can construct a Quad-Tree from a two-dimensional area using the following steps:

1.  If the current grid has the same value (i.e all `1's` or all `0's`) set `isLeaf` True and set `val` to the value of the grid and set the four children to Null and stop.
2.  If the current grid has different values, set `isLeaf` to False and set `val` to any value and divide the current grid into four sub-grids as shown in the photo.
3.  Recurse for each of the children with the proper sub-grid.

If you want to know more about the Quad-Tree, you can refer to the [wiki](https://en.wikipedia.org/wiki/Quadtree).

**Quad-Tree format:**

The input/output represents the serialized format of a Quad-Tree using level order traversal, where `null` signifies a path terminator where no node exists below.

It is very similar to the serialization of the binary tree. The only difference is that the node is represented as a list `[isLeaf, val]`.

If the value of `isLeaf` or `val` is True we represent it as **1** in the list `[isLeaf, val]` and if the value of `isLeaf` or `val` is False we represent it as **0**.

**Example 1:**

**Input:** quadTree1 = \[\[0,1\],\[1,1\],\[1,1\],\[1,0\],\[1,0\]\]
, quadTree2 = \[\[0,1\],\[1,1\],\[0,1\],\[1,1\],\[1,0\],null,null,null,null,\[1,0\],\[1,0\],\[1,1\],\[1,1\]\]
**Output:** \[\[0,0\],\[1,1\],\[1,1\],\[1,1\],\[1,0\]\]
**Explanation:** quadTree1 and quadTree2 are shown above. You can see the binary matrix which is represented by each Quad-Tree.
If we apply logical bitwise OR on the two binary matrices we get the binary matrix below which is represented by the result Quad-Tree.
Notice that the binary matrices shown are only for illustration, you don't have to construct the binary matrix to get the result tree.

**Example 2:**

**Input:** quadTree1 = \[\[1,0\]\], quadTree2 = \[\[1,0\]\]
**Output:** \[\[1,0\]\]
**Explanation:** Each tree represents a binary matrix of size 1\*1. Each matrix contains only zero.
The resulting matrix is of size 1\*1 with also zero.

**Constraints:**

*   `quadTree1` and `quadTree2` are both **valid** Quad-Trees each representing a `n * n` grid.
*   `n == 2x` where `0 <= x <= 9`.

## A solution in Java

```java
class Solution {
    public Node intersect(Node quadTree1, Node quadTree2) {
        if (quadTree1.isLeaf) {
            return quadTree1.val ? quadTree1 : quadTree2;
        }
        if (quadTree2.isLeaf) {
            return quadTree2.val ? quadTree2 : quadTree1;
        }

        quadTree1.topLeft = intersect(quadTree1.topLeft, quadTree2.topLeft);
        quadTree1.topRight = intersect(quadTree1.topRight, quadTree2.topRight);
        quadTree1.bottomLeft = intersect(quadTree1.bottomLeft, quadTree2.bottomLeft);
        quadTree1.bottomRight = intersect(quadTree1.bottomRight, quadTree2.bottomRight);

        if (quadTree1.topLeft.isLeaf && quadTree1.topRight.isLeaf &&
            quadTree1.bottomLeft.isLeaf && quadTree1.bottomRight.isLeaf &&
            quadTree1.topLeft.val == quadTree1.topRight.val &&
            quadTree1.topLeft.val == quadTree1.bottomLeft.val &&
            quadTree1.topLeft.val == quadTree1.bottomRight.val) {
            quadTree1.isLeaf = true;
            quadTree1.val = quadTree1.topLeft.val;
        }
        return quadTree1;
    }
}
```
The given binary matrices are represented using Quad Trees. We need to find another Quad Tree that represents the bitwise OR of the two binary matrices.

For the given problem, since doing bitwise OR makes 1's dominate, we only need to focus on the trees where a leaf node has value 1, as that overrides any other case.

The algorithm to solve this problem is as follows:
1. If either quadTree1 or quadTree2 has a leaf node with value 1, choose that node as the result.
2. If neither quadTree1 nor quadTree2 is a leaf node, perform the bitwise OR for each of the 4 children of the quad trees and save the comparison results.
3. If all children nodes are leaves with the same value, update the current node as a leaf with the common value, otherwise, update the children nodes.

At the end of the recursion, we will have a new Quad Tree representing the bitwise OR of the given binary matrices.

## A solution in C++

```cpp
class Node {
public:
    bool val;
    bool isLeaf;
    Node* topLeft;
    Node* topRight;
    Node* bottomLeft;
    Node* bottomRight;
};

class Solution {
public:
    Node* intersect(Node* quadTree1, Node* quadTree2) {
        if (quadTree1->isLeaf) {
            return (quadTree1->val) ? quadTree1 : quadTree2;
        } else if (quadTree2->isLeaf) {
            return (quadTree2->val) ? quadTree2 : quadTree1;
        } else {
            Node* topLeft = intersect(quadTree1->topLeft, quadTree2->topLeft);
            Node* topRight = intersect(quadTree1->topRight, quadTree2->topRight);
            Node* bottomLeft = intersect(quadTree1->bottomLeft, quadTree2->bottomLeft);
            Node* bottomRight = intersect(quadTree1->bottomRight, quadTree2->bottomRight);
            if (topLeft->isLeaf && topRight->isLeaf && bottomLeft->isLeaf && bottomRight->isLeaf &&
                topLeft->val == topRight->val && topLeft->val == bottomLeft->val && topLeft->val == bottomRight->val) {
                quadTree1->isLeaf = true;
                quadTree1->val = topLeft->val;
                delete quadTree1->topLeft;
                delete quadTree1->topRight;
                delete quadTree1->bottomLeft;
                delete quadTree1->bottomRight;
            } else {
                quadTree1->topLeft = topLeft;
                quadTree1->topRight = topRight;
                quadTree1->bottomLeft = bottomLeft;
                quadTree1->bottomRight = bottomRight;
            }
            return quadTree1;
        }
    }
};
```
The given binary matrices are represented using Quad Trees. We need to find another Quad Tree that represents the bitwise OR of the two binary matrices.

For the given problem, since doing bitwise OR makes 1's dominate, we only need to focus on the trees where a leaf node has value 1, as that overrides any other case.

The algorithm to solve this problem is as follows:
1. If either quadTree1 or quadTree2 has a leaf node with value 1, choose that node as the result.
2. If neither quadTree1 nor quadTree2 is a leaf node, perform the bitwise OR for each of the 4 children of the quad trees and save the comparison results.
3. If all children nodes are leaves with the same value, update the current node as a leaf with the common value, otherwise, update the children nodes.

At the end of the recursion, we will have a new Quad Tree representing the bitwise OR of the given binary matrices.

## A solution in Python

```python
class Node:
    def __init__(self, val, isLeaf, topLeft, topRight, bottomLeft, bottomRight):
        self.val = val
        self.isLeaf = isLeaf
        self.topLeft = topLeft
        self.topRight = topRight
        self.bottomLeft = bottomLeft
        self.bottomRight = bottomRight

class Solution:
    def intersect(self, quadTree1: 'Node', quadTree2: 'Node') -> 'Node':
        if quadTree1.isLeaf:
            return quadTree1 if quadTree1.val else quadTree2
        if quadTree2.isLeaf:
            return quadTree2 if quadTree2.val else quadTree1

        quadTree1.topLeft = self.intersect(quadTree1.topLeft, quadTree2.topLeft)
        quadTree1.topRight = self.intersect(quadTree1.topRight, quadTree2.topRight)
        quadTree1.bottomLeft = self.intersect(quadTree1.bottomLeft, quadTree2.bottomLeft)
        quadTree1.bottomRight = self.intersect(quadTree1.bottomRight, quadTree2.bottomRight)

        if (quadTree1.topLeft.isLeaf and quadTree1.topRight.isLeaf and
            quadTree1.bottomLeft.isLeaf and quadTree1.bottomRight.isLeaf and
            quadTree1.topLeft.val == quadTree1.topRight.val and
            quadTree1.topLeft.val == quadTree1.bottomLeft.val and
            quadTree1.topLeft.val == quadTree1.bottomRight.val):
            quadTree1.isLeaf = True
            quadTree1.val = quadTree1.topLeft.val

        return quadTree1
```
The given binary matrices are represented using Quad Trees. We need to find another Quad Tree that represents the bitwise OR of the two binary matrices.

For the given problem, since doing bitwise OR makes 1's dominate, we only need to focus on the trees where a leaf node has value 1, as that overrides any other case.

The algorithm to solve this problem is as follows:
1. If either quadTree1 or quadTree2 has a leaf node with value 1, choose that node as the result.
2. If neither quadTree1 nor quadTree2 is a leaf node, perform the bitwise OR for each of the 4 children of the quad trees and save the comparison results.
3. If all children nodes are leaves with the same value, update the current node as a leaf with the common value, otherwise, update the children nodes.

At the end of the recursion, we will have a new Quad Tree representing the bitwise OR of the given binary matrices.

## A solution in Javascript

```javascript
class Node {
    constructor(val, isLeaf, topLeft, topRight, bottomLeft, bottomRight) {
        this.val = val;
        this.isLeaf = isLeaf;
        this.topLeft = topLeft;
        this.topRight = topRight;
        this.bottomLeft = bottomLeft;
        this.bottomRight = bottomRight;
    }
};

var intersect = function(quadTree1, quadTree2) {
    if (quadTree1.isLeaf) {
        return quadTree1.val ? quadTree1 : quadTree2;
    }
    if (quadTree2.isLeaf) {
        return quadTree2.val ? quadTree2 : quadTree1;
    }

    quadTree1.topLeft = intersect(quadTree1.topLeft, quadTree2.topLeft);
    quadTree1.topRight = intersect(quadTree1.topRight, quadTree2.topRight);
    quadTree1.bottomLeft = intersect(quadTree1.bottomLeft, quadTree2.bottomLeft);
    quadTree1.bottomRight = intersect(quadTree1.bottomRight, quadTree2.bottomRight);

    if (quadTree1.topLeft.isLeaf && quadTree1.topRight.isLeaf && quadTree1.bottomLeft.isLeaf &&
        quadTree1.bottomRight.isLeaf && quadTree1.topLeft.val == quadTree1.topRight.val &&
        quadTree1.topLeft.val == quadTree1.bottomLeft.val && quadTree1.topLeft.val == quadTree1.bottomRight.val) {
        quadTree1.isLeaf = true;
        quadTree1.val = quadTree1.topLeft.val;
    }
    return quadTree1;
};
```
The given binary matrices are represented using Quad Trees. We need to find another Quad Tree that represents the bitwise OR of the two binary matrices.

For the given problem, since doing bitwise OR makes 1's dominate, we only need to focus on the trees where a leaf node has value 1, as that overrides any other case.

The algorithm to solve this problem is as follows:
1. If either quadTree1 or quadTree2 has a leaf node with value 1, choose that node as the result.
2. If neither quadTree1 nor quadTree2 is a leaf node, perform the bitwise OR for each of the 4 children of the quad trees and save the comparison results.
3. If all children nodes are leaves with the same value, update the current node as a leaf with the common value, otherwise, update the children nodes.

At the end of the recursion, we will have a new Quad Tree representing the bitwise OR of the given binary matrices.


# Maximum Depth of N-ary Tree

- slug: maximum-depth-of-n-ary-tree
- difficulty: Easy

Given a n-ary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

_Nary-Tree input serialization is represented in their level order traversal, each group of children is separated by the null value (See examples)._

**Example 1:**

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

**Example 2:**

**Input:** root = \[1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14\]
**Output:** 5

**Constraints:**

*   The total number of nodes is in the range `[0, 104]`.
*   The depth of the n-ary tree is less than or equal to `1000`.

## A solution in Java

```java
import java.util.List;

public class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
}

public int maxDepth(Node root) {
    if (root == null) return 0;
    int maxDepth = 0;
    for (Node child : root.children) {
        maxDepth = Math.max(maxDepth, maxDepth(child));
    }
    return maxDepth + 1;
}
```
The algorithm used for all the language implementations is Depth First Traversal. The base case checks if the current root is `null` or not. If it is `null`, the function returns 0. Then, we iterate through each child node in the `children` list and calculate the maximum depth from each child node by making a recursive call. The maximum depth from a child node is added to the current depth which is initialized to 0. Finally, we return the maximum depth + 1 to account for the current node.

## A solution in C++

```cpp
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};

int maxDepth(Node* root) {
    if (!root) return 0;
    int max_depth = 0;
    for (Node* child : root->children) {
        max_depth = max(max_depth, maxDepth(child));
    }
    return max_depth + 1;
}
```
The algorithm used for all the language implementations is Depth First Traversal. The base case checks if the current root is `null` or not. If it is `null`, the function returns 0. Then, we iterate through each child node in the `children` list and calculate the maximum depth from each child node by making a recursive call. The maximum depth from a child node is added to the current depth which is initialized to 0. Finally, we return the maximum depth + 1 to account for the current node.

## A solution in Python

```python
class Node:
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children if children is not None else []

def max_depth(root):
    if root is None:
        return 0
    max_depth = 0
    for child in root.children:
        max_depth = max(max_depth, max_depth(child))
    return max_depth + 1
```
The algorithm used for all the language implementations is Depth First Traversal. The base case checks if the current root is `null` or not. If it is `null`, the function returns 0. Then, we iterate through each child node in the `children` list and calculate the maximum depth from each child node by making a recursive call. The maximum depth from a child node is added to the current depth which is initialized to 0. Finally, we return the maximum depth + 1 to account for the current node.

## A solution in Javascript

```javascript
class Node {
    constructor(val, children) {
        this.val = val;
        this.children = children ? children : [];
    }
}

function maxDepth(root) {
    if (!root) return 0;
    let maxDepth = 0;
    for (const child of root.children) {
        maxDepth = Math.max(maxDepth, maxDepth(child));
    }
    return maxDepth + 1;
}
```
The algorithm used for all the language implementations is Depth First Traversal. The base case checks if the current root is `null` or not. If it is `null`, the function returns 0. Then, we iterate through each child node in the `children` list and calculate the maximum depth from each child node by making a recursive call. The maximum depth from a child node is added to the current depth which is initialized to 0. Finally, we return the maximum depth + 1 to account for the current node.


# Subarray Sum Equals K

- slug: subarray-sum-equals-k
- difficulty: Medium

Given an array of integers `nums` and an integer `k`, return _the total number of subarrays whose sum equals to_ `k`.

A subarray is a contiguous **non-empty** sequence of elements within an array.

**Example 1:**

**Input:** nums = \[1,1,1\], k = 2
**Output:** 2

**Example 2:**

**Input:** nums = \[1,2,3\], k = 3
**Output:** 2

**Constraints:**

*   `1 <= nums.length <= 2 * 104`
*   `-1000 <= nums[i] <= 1000`
*   `-107 <= k <= 107`

## A solution in Java

```java
public int subarraySum(int[] nums, int k) {
    Map<Integer, Integer> prefixSumFrequency = new HashMap<>();
    prefixSumFrequency.put(0, 1);
    int prefixSum = 0, result = 0;

    for (int num : nums) {
        prefixSum += num;
        result += prefixSumFrequency.getOrDefault(prefixSum - k, 0);
        prefixSumFrequency.put(prefixSum, prefixSumFrequency.getOrDefault(prefixSum, 0) + 1);
    }

    return result;
}
```
The algorithm utilizes a hash map to store the frequency of the prefix sum up to the current element in the array. We start by initializing the hash map with a key-value pair (0, 1), which represents the empty subarray sum. Then we iterate through the input array, updating the prefix sum and result.

For each element in the array, we increment the prefix sum by the value of the element. We then increment the result by the value of the key (prefix sum - k) in the hash map, using a default value of 0 if the key is not found. This represents the number of subarrays ending at the current index with the sum equal to k. Finally, we increment the value of the prefix sum key in the hash map.

The time complexity of the algorithm is O(n), where n is the length of the input array. This is because we iterate through the array once and perform constant time operations for each element. The space complexity is O(n), which comes from using the hash map to store frequency of prefix sums.

## A solution in C++

```cpp
int subarraySum(vector<int>& nums, int k) {
    unordered_map<int, int> prefixSumFrequency;
    prefixSumFrequency[0] = 1;
    int prefixSum = 0, result = 0;

    for (int num : nums) {
        prefixSum += num;
        result += prefixSumFrequency[prefixSum - k];
        prefixSumFrequency[prefixSum]++;
    }

    return result;
}
```
The algorithm utilizes a hash map to store the frequency of the prefix sum up to the current element in the array. We start by initializing the hash map with a key-value pair (0, 1), which represents the empty subarray sum. Then we iterate through the input array, updating the prefix sum and result.

For each element in the array, we increment the prefix sum by the value of the element. We then increment the result by the value of the key (prefix sum - k) in the hash map, using a default value of 0 if the key is not found. This represents the number of subarrays ending at the current index with the sum equal to k. Finally, we increment the value of the prefix sum key in the hash map.

The time complexity of the algorithm is O(n), where n is the length of the input array. This is because we iterate through the array once and perform constant time operations for each element. The space complexity is O(n), which comes from using the hash map to store frequency of prefix sums.

## A solution in Python

```python
def subarraySum(nums, k):
    prefix_sum_frequency = {0: 1}
    prefix_sum, result = 0, 0

    for num in nums:
        prefix_sum += num
        result += prefix_sum_frequency.get(prefix_sum - k, 0)
        prefix_sum_frequency[prefix_sum] = prefix_sum_frequency.get(prefix_sum, 0) + 1

    return result
```
The algorithm utilizes a hash map to store the frequency of the prefix sum up to the current element in the array. We start by initializing the hash map with a key-value pair (0, 1), which represents the empty subarray sum. Then we iterate through the input array, updating the prefix sum and result.

For each element in the array, we increment the prefix sum by the value of the element. We then increment the result by the value of the key (prefix sum - k) in the hash map, using a default value of 0 if the key is not found. This represents the number of subarrays ending at the current index with the sum equal to k. Finally, we increment the value of the prefix sum key in the hash map.

The time complexity of the algorithm is O(n), where n is the length of the input array. This is because we iterate through the array once and perform constant time operations for each element. The space complexity is O(n), which comes from using the hash map to store frequency of prefix sums.

## A solution in Javascript

```javascript
function subarraySum(nums, k) {
    const prefixSumFrequency = {0: 1};
    let prefixSum = 0, result = 0;

    for (const num of nums) {
        prefixSum += num;
        result += (prefixSumFrequency[prefixSum - k] || 0);
        prefixSumFrequency[prefixSum] = (prefixSumFrequency[prefixSum] || 0) + 1;
    }

    return result;
}
```
The algorithm utilizes a hash map to store the frequency of the prefix sum up to the current element in the array. We start by initializing the hash map with a key-value pair (0, 1), which represents the empty subarray sum. Then we iterate through the input array, updating the prefix sum and result.

For each element in the array, we increment the prefix sum by the value of the element. We then increment the result by the value of the key (prefix sum - k) in the hash map, using a default value of 0 if the key is not found. This represents the number of subarrays ending at the current index with the sum equal to k. Finally, we increment the value of the prefix sum key in the hash map.

The time complexity of the algorithm is O(n), where n is the length of the input array. This is because we iterate through the array once and perform constant time operations for each element. The space complexity is O(n), which comes from using the hash map to store frequency of prefix sums.


# Array Partition

- slug: array-partition
- difficulty: Easy

Given an integer array `nums` of `2n` integers, group these integers into `n` pairs `(a1, b1), (a2, b2), ..., (an, bn)` such that the sum of `min(ai, bi)` for all `i` is **maximized**. Return _the maximized sum_.

**Example 1:**

**Input:** nums = \[1,4,3,2\]
**Output:** 4
**Explanation:** All possible pairings (ignoring the ordering of elements) are:
1. (1, 4), (2, 3) -> min(1, 4) + min(2, 3) = 1 + 2 = 3
2. (1, 3), (2, 4) -> min(1, 3) + min(2, 4) = 1 + 2 = 3
3. (1, 2), (3, 4) -> min(1, 2) + min(3, 4) = 1 + 3 = 4
So the maximum possible sum is 4.

**Example 2:**

**Input:** nums = \[6,2,6,5,1,2\]
**Output:** 9
**Explanation:** The optimal pairing is (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9.

**Constraints:**

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

## A solution in Java

```java
import java.util.Arrays;

public int arrayPairSum(int[] nums) {
    Arrays.sort(nums);
    int sum = 0;
    for (int i = 0; i < nums.length; i += 2) {
        sum += nums[i];
    }
    return sum;
}
```
1. First, sort the given 'nums' array/vector in ascending order.
2. Iterate over the sorted array, with a step of 2, starting from index 0.
3. During the iteration, accumulate the sum of every ith element (from sorted array) to maximize the sum of minimum elements in pairs.
4. Return the accumulated sum.

## A solution in C++

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

int arrayPairSum(std::vector<int>& nums) {
    std::sort(nums.begin(), nums.end());
    int sum = 0;
    for (int i = 0; i < nums.size(); i += 2) {
        sum += nums[i];
    }
    return sum;
}
```
1. First, sort the given 'nums' array/vector in ascending order.
2. Iterate over the sorted array, with a step of 2, starting from index 0.
3. During the iteration, accumulate the sum of every ith element (from sorted array) to maximize the sum of minimum elements in pairs.
4. Return the accumulated sum.

## A solution in Python

```python
def array_pair_sum(nums):
    nums.sort()
    return sum(nums[::2])
```
1. First, sort the given 'nums' array/vector in ascending order.
2. Iterate over the sorted array, with a step of 2, starting from index 0.
3. During the iteration, accumulate the sum of every ith element (from sorted array) to maximize the sum of minimum elements in pairs.
4. Return the accumulated sum.

## A solution in Javascript

```javascript
function arrayPairSum(nums) {
    nums.sort((a, b) => a - b);
    let sum = 0;
    for (let i = 0; i < nums.length; i += 2) {
        sum += nums[i];
    }
    return sum;
}
```
1. First, sort the given 'nums' array/vector in ascending order.
2. Iterate over the sorted array, with a step of 2, starting from index 0.
3. During the iteration, accumulate the sum of every ith element (from sorted array) to maximize the sum of minimum elements in pairs.
4. Return the accumulated sum.


# Longest Line of Consecutive One in Matrix

- slug: longest-line-of-consecutive-one-in-matrix
- difficulty: Medium

Given an `m x n` binary matrix `mat`, return _the length of the longest line of consecutive one in the matrix_.

The line could be horizontal, vertical, diagonal, or anti-diagonal.

**Example 1:**

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

**Example 2:**

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

**Constraints:**

*   `m == mat.length`
*   `n == mat[i].length`
*   `1 <= m, n <= 104`
*   `1 <= m * n <= 104`
*   `mat[i][j]` is either `0` or `1`.

## A solution in Java

```java
public int longestLine(int[][] mat) {
    int rows = mat.length;
    int cols = mat[0].length;
    int max_length = 0;
    int[][][] dp = new int[rows][cols][4];

    for (int r = 0; r < rows; ++r) {
        for (int c = 0; c < cols; ++c) {
            if (mat[r][c] == 1) {
                dp[r][c][0] = r > 0 ? dp[r - 1][c][0] + 1 : 1;
                dp[r][c][1] = c > 0 ? dp[r][c - 1][1] + 1 : 1;
                dp[r][c][2] = (r > 0 && c > 0) ? dp[r - 1][c - 1][2] + 1 : 1;
                dp[r][c][3] = (r > 0 && c < cols - 1) ? dp[r - 1][c + 1][3] + 1 : 1;
                max_length = Math.max(max_length, Math.max(dp[r][c][0], Math.max(dp[r][c][1], Math.max(dp[r][c][2], dp[r][c][3]))));
            }
        }
    }
    return max_length;
}
```
The algorithm uses dynamic programming to find the longest line of consecutive ones in the binary matrix. We create a 3D array `dp` with dimensions (rows x cols x 4). For each element (i, j, k) of `dp`, it represents the length of the longest line ending at mat[i, j] in the direction specified by k (0: horizontal, 1: vertical, 2: diagonal, 3: anti-diagonal).

1. For each cell mat[i][j], if the cell value is 1, update dp[i][j][0], dp[i][j][1], dp[i][j][2], and dp[i][j][3].
2. Update the maximum length to be the maximum value of the current line lengths (dp[i][j][0], dp[i][j][1], dp[i][j][2], and dp[i][j][3]) if they are greater than the current maximum length.
3. Return the maximum length found.

The time complexity of this algorithm is O(m * n) where m and n are the numbers of rows and columns in the matrix, respectively. The space complexity is also O(m * n) due to the use of the auxiliary `dp` array.

## A solution in C++

```cpp
int longestLine(vector<vector<int>>& mat) {
    int rows = mat.size();
    int cols = mat[0].size();
    int max_length = 0;
    vector<vector<vector<int>>> dp(rows, vector<vector<int>>(cols, vector<int>(4, 0)));

    for (int r = 0; r < rows; ++r) {
        for (int c = 0; c < cols; ++c) {
            if (mat[r][c] == 1) {
                dp[r][c][0] = r > 0 ? dp[r - 1][c][0] + 1 : 1;
                dp[r][c][1] = c > 0 ? dp[r][c - 1][1] + 1 : 1;
                dp[r][c][2] = (r > 0 && c > 0) ? dp[r - 1][c - 1][2] + 1 : 1;
                dp[r][c][3] = (r > 0 && c < cols - 1) ? dp[r - 1][c + 1][3] + 1 : 1;
                max_length = max(max_length, max(dp[r][c][0], max(dp[r][c][1], max(dp[r][c][2], dp[r][c][3]))));
            }
        }
    }
    return max_length;
}
```
The algorithm uses dynamic programming to find the longest line of consecutive ones in the binary matrix. We create a 3D array `dp` with dimensions (rows x cols x 4). For each element (i, j, k) of `dp`, it represents the length of the longest line ending at mat[i, j] in the direction specified by k (0: horizontal, 1: vertical, 2: diagonal, 3: anti-diagonal).

1. For each cell mat[i][j], if the cell value is 1, update dp[i][j][0], dp[i][j][1], dp[i][j][2], and dp[i][j][3].
2. Update the maximum length to be the maximum value of the current line lengths (dp[i][j][0], dp[i][j][1], dp[i][j][2], and dp[i][j][3]) if they are greater than the current maximum length.
3. Return the maximum length found.

The time complexity of this algorithm is O(m * n) where m and n are the numbers of rows and columns in the matrix, respectively. The space complexity is also O(m * n) due to the use of the auxiliary `dp` array.

## A solution in Python

```python
def longestLine(mat):
    rows, cols = len(mat), len(mat[0])
    max_length = 0
    dp = [[[0, 0, 0, 0] for _ in range(cols)] for _ in range(rows)]

    for r in range(rows):
        for c in range(cols):
            if mat[r][c] == 1:
                dp[r][c][0] = dp[r - 1][c][0] + 1 if r > 0 else 1
                dp[r][c][1] = dp[r][c - 1][1] + 1 if c > 0 else 1
                dp[r][c][2] = dp[r - 1][c - 1][2] + 1 if r > 0 and c > 0 else 1
                dp[r][c][3] = dp[r - 1][c + 1][3] + 1 if r > 0 and c < cols - 1 else 1
                max_length = max(max_length, max(dp[r][c]))

    return max_length
```
The algorithm uses dynamic programming to find the longest line of consecutive ones in the binary matrix. We create a 3D array `dp` with dimensions (rows x cols x 4). For each element (i, j, k) of `dp`, it represents the length of the longest line ending at mat[i, j] in the direction specified by k (0: horizontal, 1: vertical, 2: diagonal, 3: anti-diagonal).

1. For each cell mat[i][j], if the cell value is 1, update dp[i][j][0], dp[i][j][1], dp[i][j][2], and dp[i][j][3].
2. Update the maximum length to be the maximum value of the current line lengths (dp[i][j][0], dp[i][j][1], dp[i][j][2], and dp[i][j][3]) if they are greater than the current maximum length.
3. Return the maximum length found.

The time complexity of this algorithm is O(m * n) where m and n are the numbers of rows and columns in the matrix, respectively. The space complexity is also O(m * n) due to the use of the auxiliary `dp` array.

## A solution in Javascript

```javascript
function longestLine(mat) {
    const rows = mat.length;
    const cols = mat[0].length;
    let max_length = 0;
    const dp = Array.from(Array(rows), () => Array.from(Array(cols), () => Array(4).fill(0)));

    for (let r = 0; r < rows; ++r) {
        for (let c = 0; c < cols; ++c) {
            if (mat[r][c] === 1) {
                dp[r][c][0] = r > 0 ? dp[r - 1][c][0] + 1 : 1;
                dp[r][c][1] = c > 0 ? dp[r][c - 1][1] + 1 : 1;
                dp[r][c][2] = (r > 0 && c > 0) ? dp[r - 1][c - 1][2] + 1 : 1;
                dp[r][c][3] = (r > 0 && c < cols - 1) ? dp[r - 1][c + 1][3] + 1 : 1;
                max_length = Math.max(max_length, Math.max(...dp[r][c]));
            }
        }
    }
    return max_length;
}
```
The algorithm uses dynamic programming to find the longest line of consecutive ones in the binary matrix. We create a 3D array `dp` with dimensions (rows x cols x 4). For each element (i, j, k) of `dp`, it represents the length of the longest line ending at mat[i, j] in the direction specified by k (0: horizontal, 1: vertical, 2: diagonal, 3: anti-diagonal).

1. For each cell mat[i][j], if the cell value is 1, update dp[i][j][0], dp[i][j][1], dp[i][j][2], and dp[i][j][3].
2. Update the maximum length to be the maximum value of the current line lengths (dp[i][j][0], dp[i][j][1], dp[i][j][2], and dp[i][j][3]) if they are greater than the current maximum length.
3. Return the maximum length found.

The time complexity of this algorithm is O(m * n) where m and n are the numbers of rows and columns in the matrix, respectively. The space complexity is also O(m * n) due to the use of the auxiliary `dp` array.


# Binary Tree Tilt

- slug: binary-tree-tilt
- difficulty: Easy

Given the `root` of a binary tree, return _the sum of every tree node's **tilt**._

The **tilt** of a tree node is the **absolute difference** between the sum of all left subtree node **values** and all right subtree node **values**. If a node does not have a left child, then the sum of the left subtree node **values** is treated as `0`. The rule is similar if the node does not have a right child.

**Example 1:**

**Input:** root = \[1,2,3\]
**Output:** 1
**Explanation:**
Tilt of node 2 : |0-0| = 0 (no children)
Tilt of node 3 : |0-0| = 0 (no children)
Tilt of node 1 : |2-3| = 1 (left subtree is just left child, so sum is 2; right subtree is just right child, so sum is 3)
Sum of every tilt : 0 + 0 + 1 = 1

**Example 2:**

**Input:** root = \[4,2,9,3,5,null,7\]
**Output:** 15
**Explanation:**
Tilt of node 3 : |0-0| = 0 (no children)
Tilt of node 5 : |0-0| = 0 (no children)
Tilt of node 7 : |0-0| = 0 (no children)
Tilt of node 2 : |3-5| = 2 (left subtree is just left child, so sum is 3; right subtree is just right child, so sum is 5)
Tilt of node 9 : |0-7| = 7 (no left child, so sum is 0; right subtree is just right child, so sum is 7)
Tilt of node 4 : |(3+5+2)-(9+7)| = |10-16| = 6 (left subtree values are 3, 5, and 2, which sums to 10; right subtree values are 9 and 7, which sums to 16)
Sum of every tilt : 0 + 0 + 0 + 2 + 7 + 6 = 15

**Example 3:**

**Input:** root = \[21,7,14,1,1,2,2,3,3\]
**Output:** 9

**Constraints:**

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

## A solution in Java

```java
public int findTilt(TreeNode root) {
    int[] tiltSum = new int[] {0};
    findTiltUtil(root, tiltSum);
    return tiltSum[0];
}

private int findTiltUtil(TreeNode root, int[] tiltSum) {
    if (root == null) {
        return 0;
    }

    int leftSum = findTiltUtil(root.left, tiltSum);
    int rightSum = findTiltUtil(root.right, tiltSum);

    tiltSum[0] += Math.abs(leftSum - rightSum);
    return root.val + leftSum + rightSum;
}
```
The problem can be solved using a bottom-uprecursive algorithm. The helper function `findTiltUtil` should return two values: the sum of the current node and its descendants and the tilt value of the current node and its descendants.

The base case is when the current node is null, in this case, return [0, 0].

If the current node is not null, recursively call the `findTiltUtil` for left and right children. Then add the sum of the left child and the right child's sum, plus the value of the current node to get the new sum. For the new tilt value, add the absolute difference between the left and right child's sum to the tilt value of both children.

Finally, return the new sum and tilt value as a tuple or a list. When calling this helper function for the root, the tilt value of the whole tree will be in the second element of the result list.

## A solution in C++

```cpp
int findTiltUtil(TreeNode* root, int& tiltSum) {
    if (!root) return 0;

    int leftSum = findTiltUtil(root->left, tiltSum);
    int rightSum = findTiltUtil(root->right, tiltSum);

    tiltSum += abs(leftSum - rightSum);
    return root->val + leftSum + rightSum;
}

int findTilt(TreeNode* root) {
    int tiltSum = 0;
    findTiltUtil(root, tiltSum);
    return tiltSum;
}
```
The problem can be solved using a bottom-uprecursive algorithm. The helper function `findTiltUtil` should return two values: the sum of the current node and its descendants and the tilt value of the current node and its descendants.

The base case is when the current node is null, in this case, return [0, 0].

If the current node is not null, recursively call the `findTiltUtil` for left and right children. Then add the sum of the left child and the right child's sum, plus the value of the current node to get the new sum. For the new tilt value, add the absolute difference between the left and right child's sum to the tilt value of both children.

Finally, return the new sum and tilt value as a tuple or a list. When calling this helper function for the root, the tilt value of the whole tree will be in the second element of the result list.

## A solution in Python

```python
def findTilt(self, root):
    def findTiltUtil(node):
        if not node: return 0, 0

        leftSum, leftTilt = findTiltUtil(node.left)
        rightSum, rightTilt = findTiltUtil(node.right)

        return (node.val + leftSum + rightSum, abs(leftSum - rightSum) + leftTilt + rightTilt)

    return findTiltUtil(root)[1]
```
The problem can be solved using a bottom-uprecursive algorithm. The helper function `findTiltUtil` should return two values: the sum of the current node and its descendants and the tilt value of the current node and its descendants.

The base case is when the current node is null, in this case, return [0, 0].

If the current node is not null, recursively call the `findTiltUtil` for left and right children. Then add the sum of the left child and the right child's sum, plus the value of the current node to get the new sum. For the new tilt value, add the absolute difference between the left and right child's sum to the tilt value of both children.

Finally, return the new sum and tilt value as a tuple or a list. When calling this helper function for the root, the tilt value of the whole tree will be in the second element of the result list.

## A solution in Javascript

```javascript
function findTilt(root) {
    function findTiltUtil(node) {
        if (!node) return [0, 0];

        let [leftSum, leftTilt] = findTiltUtil(node.left);
        let [rightSum, rightTilt] = findTiltUtil(node.right);

        return [node.val + leftSum + rightSum, Math.abs(leftSum - rightSum) + leftTilt + rightTilt];
    }

    return findTiltUtil(root)[1];
};
```
The problem can be solved using a bottom-uprecursive algorithm. The helper function `findTiltUtil` should return two values: the sum of the current node and its descendants and the tilt value of the current node and its descendants.

The base case is when the current node is null, in this case, return [0, 0].

If the current node is not null, recursively call the `findTiltUtil` for left and right children. Then add the sum of the left child and the right child's sum, plus the value of the current node to get the new sum. For the new tilt value, add the absolute difference between the left and right child's sum to the tilt value of both children.

Finally, return the new sum and tilt value as a tuple or a list. When calling this helper function for the root, the tilt value of the whole tree will be in the second element of the result list.


# Find the Closest Palindrome

- slug: find-the-closest-palindrome
- difficulty: Hard

Given a string `n` representing an integer, return _the closest integer (not including itself), which is a palindrome_. If there is a tie, return _**the smaller one**_.

The closest is defined as the absolute difference minimized between two integers.

**Example 1:**

**Input:** n =  "123 "
**Output:**  "121 "

**Example 2:**

**Input:** n =  "1 "
**Output:**  "0 "
**Explanation:** 0 and 2 are the closest palindromes but we return the smallest which is 0.

**Constraints:**

*   `1 <= n.length <= 18`
*   `n` consists of only digits.
*   `n` does not have leading zeros.
*   `n` is representing an integer in the range `[1, 1018 - 1]`.

## A solution in Java

```java
public class ClosestPalindrome {
    public static boolean isPalindrome(String str) {
        int left = 0;
        int right = str.length() - 1;
        while (left < right) {
            if (str.charAt(left) != str.charAt(right)) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }

    public static int closestPalindrome(String n) {
        int num = Integer.parseInt(n);
        int left = num - 1;
        int right = num + 1;

        while (true) {
            if (isPalindrome(Integer.toString(left))) {
                return left;
            }
            if (isPalindrome(Integer.toString(right))) {
                return right;
            }
            left--;
            right++;
        }
    }
}
```
The algorithm works as follows:

1. Define a function `isPalindrome` that checks if a given string is a palindrome. This function uses two pointers, one at the left end and one at the right-end of the string, and compares the characters at these positions. If the characters are different, the string is not a palindrome. If the pointers cross or meet, the entire string has been checked, and it is a palindrome.
2. Define the `closestPalindrome` function that takes a string representing an integer as input. Convert the input string to an integer.
3. Initialize two variables, `left` and `right`, to represent the numbers to the left and right of the input integer.
4. In a loop, check if the string representations of `left` and `right` are palindromes using the `isPalindrome` function. If either is a palindrome, return that number. Otherwise, decrement `left` and increment `right` in each iteration.

This process continues until a palindrome is found on either side of the input integer. If both are found at the same time, the smaller one is favored due to the decrement of `left` and increment of `right`, resulting in `left` being returned first.

## A solution in C++

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

bool isPalindrome(std::string str) {
    int left = 0;
    int right = str.length() - 1;
    while (left < right) {
        if (str[left] != str[right]) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

int closestPalindrome(std::string n) {
    int num = std::stoi(n);
    int left = num - 1;
    int right = num + 1;

    while (true) {
        if (isPalindrome(std::to_string(left))) {
            return left;
        }
        if (isPalindrome(std::to_string(right))) {
            return right;
        }
        left--;
        right++;
    }
}
```
The algorithm works as follows:

1. Define a function `isPalindrome` that checks if a given string is a palindrome. This function uses two pointers, one at the left end and one at the right-end of the string, and compares the characters at these positions. If the characters are different, the string is not a palindrome. If the pointers cross or meet, the entire string has been checked, and it is a palindrome.
2. Define the `closestPalindrome` function that takes a string representing an integer as input. Convert the input string to an integer.
3. Initialize two variables, `left` and `right`, to represent the numbers to the left and right of the input integer.
4. In a loop, check if the string representations of `left` and `right` are palindromes using the `isPalindrome` function. If either is a palindrome, return that number. Otherwise, decrement `left` and increment `right` in each iteration.

This process continues until a palindrome is found on either side of the input integer. If both are found at the same time, the smaller one is favored due to the decrement of `left` and increment of `right`, resulting in `left` being returned first.

## A solution in Python

```python
def is_palindrome(s: str) -> bool:
    return s == s[::-1]

def closest_palindrome(n: str) -> int:
    num = int(n)
    left = num - 1
    right = num + 1

    while True:
        if is_palindrome(str(left)):
            return left
        if is_palindrome(str(right)):
            return right
        left -= 1
        right += 1
```
The algorithm works as follows:

1. Define a function `isPalindrome` that checks if a given string is a palindrome. This function uses two pointers, one at the left end and one at the right-end of the string, and compares the characters at these positions. If the characters are different, the string is not a palindrome. If the pointers cross or meet, the entire string has been checked, and it is a palindrome.
2. Define the `closestPalindrome` function that takes a string representing an integer as input. Convert the input string to an integer.
3. Initialize two variables, `left` and `right`, to represent the numbers to the left and right of the input integer.
4. In a loop, check if the string representations of `left` and `right` are palindromes using the `isPalindrome` function. If either is a palindrome, return that number. Otherwise, decrement `left` and increment `right` in each iteration.

This process continues until a palindrome is found on either side of the input integer. If both are found at the same time, the smaller one is favored due to the decrement of `left` and increment of `right`, resulting in `left` being returned first.

## A solution in Javascript

```javascript
function isPalindrome(str) {
    let left = 0;
    let right = str.length - 1;

    while (left < right) {
        if (str[left] !== str[right]) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

function closestPalindrome(n) {
    const num = parseInt(n);
    let left = num - 1;
    let right = num + 1;

    while (true) {
        if (isPalindrome(left.toString())) {
            return left;
        }
        if (isPalindrome(right.toString())) {
            return right;
        }
        left--;
        right++;
    }
}
```
The algorithm works as follows:

1. Define a function `isPalindrome` that checks if a given string is a palindrome. This function uses two pointers, one at the left end and one at the right-end of the string, and compares the characters at these positions. If the characters are different, the string is not a palindrome. If the pointers cross or meet, the entire string has been checked, and it is a palindrome.
2. Define the `closestPalindrome` function that takes a string representing an integer as input. Convert the input string to an integer.
3. Initialize two variables, `left` and `right`, to represent the numbers to the left and right of the input integer.
4. In a loop, check if the string representations of `left` and `right` are palindromes using the `isPalindrome` function. If either is a palindrome, return that number. Otherwise, decrement `left` and increment `right` in each iteration.

This process continues until a palindrome is found on either side of the input integer. If both are found at the same time, the smaller one is favored due to the decrement of `left` and increment of `right`, resulting in `left` being returned first.


# Array Nesting

- slug: array-nesting
- difficulty: Medium

You are given an integer array `nums` of length `n` where `nums` is a permutation of the numbers in the range `[0, n - 1]`.

You should build a set `s[k] = {nums[k], nums[nums[k]], nums[nums[nums[k]]], ... }` subjected to the following rule:

*   The first element in `s[k]` starts with the selection of the element `nums[k]` of `index = k`.
*   The next element in `s[k]` should be `nums[nums[k]]`, and then `nums[nums[nums[k]]]`, and so on.
*   We stop adding right before a duplicate element occurs in `s[k]`.

Return _the longest length of a set_ `s[k]`.

**Example 1:**

**Input:** nums = \[5,4,0,3,1,6,2\]
**Output:** 4
**Explanation:**
nums\[0\] = 5, nums\[1\] = 4, nums\[2\] = 0, nums\[3\] = 3, nums\[4\] = 1, nums\[5\] = 6, nums\[6\] = 2.
One of the longest sets s\[k\]:
s\[0\] = {nums\[0\], nums\[5\], nums\[6\], nums\[2\]} = {5, 6, 2, 0}

**Example 2:**

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

**Constraints:**

*   `1 <= nums.length <= 105`
*   `0 <= nums[i] < nums.length`
*   All the values of `nums` are **unique**.

## A solution in Java

```java
public int arrayNesting(int[] nums) {
    int n = nums.length;
    int max_len = 0;
    for (int i = 0; i < n; ++i) {
        if (nums[i] != -1) {
            int start = nums[i];
            int count = 0;
            while (nums[start] != -1) {
                int temp = start;
                start = nums[start];
                count++;
                nums[temp]=-1;
            }
            max_len = Math.max(max_len, count);
        }
    }
    return max_len;
}
```
This algorithm iterates through the given `nums` array. During the iteration, when the current element `nums[i]` is not equal to -1, it initializes a new set by setting `start` to `nums[i]` and sets the `count` to 0. Then, in the inner while loop, it keeps following the chain as described in the problem statement and sets the visited element to -1. After completing the chain for the current element, it calculates the maximum length found so far and assigns it to `max_len`. This process is repeated for all elements in the `nums` array. Finally, the algorithm returns the longest length of a set `s[k]` found.

## A solution in C++

```cpp
int arrayNesting(vector<int>& nums) {
    int n = nums.size();
    int max_len = 0;
    for (int i = 0; i < n; ++i) {
        if (nums[i] != -1) {
            int start = nums[i];
            int count = 0;
            while (nums[start] != -1) {
                int temp = start;
                start = nums[start];
                count++;
                nums[temp]=-1;
            }
            max_len = max(max_len, count);
        }
    }
    return max_len;
}
```
This algorithm iterates through the given `nums` array. During the iteration, when the current element `nums[i]` is not equal to -1, it initializes a new set by setting `start` to `nums[i]` and sets the `count` to 0. Then, in the inner while loop, it keeps following the chain as described in the problem statement and sets the visited element to -1. After completing the chain for the current element, it calculates the maximum length found so far and assigns it to `max_len`. This process is repeated for all elements in the `nums` array. Finally, the algorithm returns the longest length of a set `s[k]` found.

## A solution in Python

```python
def arrayNesting(nums):
    n = len(nums)
    max_len = 0
    for i in range(n):
        if nums[i] != -1:
            start = nums[i]
            count = 0
            while nums[start] != -1:
                temp = start
                start = nums[start]
                count += 1
                nums[temp] = -1
            max_len = max(max_len, count)
    return max_len
```
This algorithm iterates through the given `nums` array. During the iteration, when the current element `nums[i]` is not equal to -1, it initializes a new set by setting `start` to `nums[i]` and sets the `count` to 0. Then, in the inner while loop, it keeps following the chain as described in the problem statement and sets the visited element to -1. After completing the chain for the current element, it calculates the maximum length found so far and assigns it to `max_len`. This process is repeated for all elements in the `nums` array. Finally, the algorithm returns the longest length of a set `s[k]` found.

## A solution in Javascript

```javascript
function arrayNesting(nums) {
    let n = nums.length;
    let max_len = 0;
    for (let i = 0; i < n; ++i) {
        if (nums[i] !== -1) {
            let start = nums[i];
            let count = 0;
            while (nums[start] !== -1) {
                let temp = start;
                start = nums[start];
                count++;
                nums[temp] = -1;
            }
            max_len = Math.max(max_len, count);
        }
    }
    return max_len;
}
```
This algorithm iterates through the given `nums` array. During the iteration, when the current element `nums[i]` is not equal to -1, it initializes a new set by setting `start` to `nums[i]` and sets the `count` to 0. Then, in the inner while loop, it keeps following the chain as described in the problem statement and sets the visited element to -1. After completing the chain for the current element, it calculates the maximum length found so far and assigns it to `max_len`. This process is repeated for all elements in the `nums` array. Finally, the algorithm returns the longest length of a set `s[k]` found.


# Reshape the Matrix

- slug: reshape-the-matrix
- difficulty: Easy

In MATLAB, there is a handy function called `reshape` which can reshape an `m x n` matrix into a new one with a different size `r x c` keeping its original data.

You are given an `m x n` matrix `mat` and two integers `r` and `c` representing the number of rows and the number of columns of the wanted reshaped matrix.

The reshaped matrix should be filled with all the elements of the original matrix in the same row-traversing order as they were.

If the `reshape` operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix.

**Example 1:**

**Input:** mat = \[\[1,2\],\[3,4\]\], r = 1, c = 4
**Output:** \[\[1,2,3,4\]\]

**Example 2:**

**Input:** mat = \[\[1,2\],\[3,4\]\], r = 2, c = 4
**Output:** \[\[1,2\],\[3,4\]\]

**Constraints:**

*   `m == mat.length`
*   `n == mat[i].length`
*   `1 <= m, n <= 100`
*   `-1000 <= mat[i][j] <= 1000`
*   `1 <= r, c <= 300`

## A solution in Java

```java
public int[][] matrixReshape(int[][] mat, int r, int c) {
    int m = mat.length;
    int n = mat[0].length;
    if (m * n != r * c) {
        return mat;
    }

    int[][] reshaped = new int[r][c];
    for (int i = 0; i < m * n; ++i) {
        reshaped[i / c][i % c] = mat[i / n][i % n];
    }

    return reshaped;
}
```
The algorithm works by first checking if the reshape operation is possible. If the total number of elements in the original matrix (m * n) is not equal to the number of elements the reshaped matrix should have (r * c), the original matrix is returned.

If the reshape operation is possible, we create a new matrix of size r x c. We then iterate through each element index (i) of the original matrix and calculate the corresponding row and column in the reshaped matrix (i / c and i % c), assigning the value from the original matrix (mat[i / n][i % n]) to its position in the reshaped matrix.

Finally, we return the reshaped matrix.

## A solution in C++

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

vector<vector<int>> matrixReshape(vector<vector<int>>& mat, int r, int c) {
    int m = mat.size();
    int n = mat[0].size();
    if (m * n != r * c) {
        return mat;
    }

    vector<vector<int>> reshaped(r, vector<int>(c));
    for (int i = 0; i < m * n; ++i) {
        reshaped[i / c][i % c] = mat[i / n][i % n];
    }

    return reshaped;
}
```
The algorithm works by first checking if the reshape operation is possible. If the total number of elements in the original matrix (m * n) is not equal to the number of elements the reshaped matrix should have (r * c), the original matrix is returned.

If the reshape operation is possible, we create a new matrix of size r x c. We then iterate through each element index (i) of the original matrix and calculate the corresponding row and column in the reshaped matrix (i / c and i % c), assigning the value from the original matrix (mat[i / n][i % n]) to its position in the reshaped matrix.

Finally, we return the reshaped matrix.

## A solution in Python

```python
def matrixReshape(mat, r, c):
    m, n = len(mat), len(mat[0])
    if m * n != r * c:
        return mat

    reshaped = [[0] * c for _ in range(r)]
    for i in range(m * n):
        reshaped[i // c][i % c] = mat[i // n][i % n]

    return reshaped
```
The algorithm works by first checking if the reshape operation is possible. If the total number of elements in the original matrix (m * n) is not equal to the number of elements the reshaped matrix should have (r * c), the original matrix is returned.

If the reshape operation is possible, we create a new matrix of size r x c. We then iterate through each element index (i) of the original matrix and calculate the corresponding row and column in the reshaped matrix (i / c and i % c), assigning the value from the original matrix (mat[i / n][i % n]) to its position in the reshaped matrix.

Finally, we return the reshaped matrix.

## A solution in Javascript

```javascript
function matrixReshape(mat, r, c) {
    const m = mat.length;
    const n = mat[0].length;
    if (m * n !== r * c) {
        return mat;
    }

    const reshaped = new Array(r).fill(null).map(() => new Array(c));
    for (let i = 0; i < m * n; ++i) {
        reshaped[Math.floor(i / c)][i % c] = mat[Math.floor(i / n)][i % n];
    }

    return reshaped;
}
```
The algorithm works by first checking if the reshape operation is possible. If the total number of elements in the original matrix (m * n) is not equal to the number of elements the reshaped matrix should have (r * c), the original matrix is returned.

If the reshape operation is possible, we create a new matrix of size r x c. We then iterate through each element index (i) of the original matrix and calculate the corresponding row and column in the reshaped matrix (i / c and i % c), assigning the value from the original matrix (mat[i / n][i % n]) to its position in the reshaped matrix.

Finally, we return the reshaped matrix.


# Permutation in String

- slug: permutation-in-string
- difficulty: Medium

Given two strings `s1` and `s2`, return `true` _if_ `s2` _contains a permutation of_ `s1`_, or_ `false` _otherwise_.

In other words, return `true` if one of `s1`'s permutations is the substring of `s2`.

**Example 1:**

**Input:** s1 =  "ab ", s2 =  "eidbaooo "
**Output:** true
**Explanation:** s2 contains one permutation of s1 ( "ba ").

**Example 2:**

**Input:** s1 =  "ab ", s2 =  "eidboaoo "
**Output:** false

**Constraints:**

*   `1 <= s1.length, s2.length <= 104`
*   `s1` and `s2` consist of lowercase English letters.

## A solution in Java

```java
public boolean checkInclusion(String s1, String s2) {
    if (s1.length() > s2.length()) return false;
    int[] s1_map = new int[26];
    int[] s2_map = new int[26];

    for (int i = 0; i < s1.length(); i++) {
        s1_map[s1.charAt(i) - 'a']++;
        s2_map[s2.charAt(i) - 'a']++;
    }

    for (int i = 0; i < s2.length() - s1.length(); i++) {
        if (Arrays.equals(s1_map, s2_map)) return true;
        s2_map[s2.charAt(i) - 'a']--;
        s2_map[s2.charAt(i + s1.length()) - 'a']++;
    }

    return Arrays.equals(s1_map, s2_map);
}
```
1. We maintain two array s1_map and s2_map to keep track of the character frequency in the respective strings.
2. If the length of s1 is larger than s2 then return false.
3. Iterate through the length of s1 and increment the count for each character in both s1_map and s2_map.
4. Now iterate through length of s2 - length of s1 to keep the sliding window of size s1.
5. If s1_map and s2_map are equal during the iterations, return true.
6. Otherwise, slide the window by updating the counts in s2_map.

The algorithm will return the result once the iterations are completed.

## A solution in C++

```cpp
#include <vector>
bool checkInclusion(std::string s1, std::string s2) {
    std::vector<int> s1_map(26, 0);
    std::vector<int> s2_map(26, 0);
    if (s1.length() > s2.length()) return false;

    for (int i = 0; i < s1.length(); ++i) {
        ++s1_map[s1[i] - 'a'];
        ++s2_map[s2[i] - 'a'];
    }

    for (int i = 0; i < s2.length() - s1.length(); ++i) {
        if (s1_map == s2_map) return true;
        --s2_map[s2[i] - 'a'];
        ++s2_map[s2[i + s1.length()] - 'a'];
    }

    return s1_map == s2_map;
}
```
1. We maintain two array s1_map and s2_map to keep track of the character frequency in the respective strings.
2. If the length of s1 is larger than s2 then return false.
3. Iterate through the length of s1 and increment the count for each character in both s1_map and s2_map.
4. Now iterate through length of s2 - length of s1 to keep the sliding window of size s1.
5. If s1_map and s2_map are equal during the iterations, return true.
6. Otherwise, slide the window by updating the counts in s2_map.

The algorithm will return the result once the iterations are completed.

## A solution in Python

```python
def checkInclusion(s1: str, s2: str) -> bool:
    if len(s1) > len(s2):
        return False

    s1_map = [0] * 26
    s2_map = [0] * 26

    for i in range(len(s1)):
        s1_map[ord(s1[i]) - ord('a')] += 1
        s2_map[ord(s2[i]) - ord('a')] += 1

    for i in range(len(s2) - len(s1)):
        if s1_map == s2_map:
            return True

        s2_map[ord(s2[i]) - ord('a')] -= 1
        s2_map[ord(s2[i + len(s1)]) - ord('a')] += 1

    return s1_map == s2_map
```
1. We maintain two array s1_map and s2_map to keep track of the character frequency in the respective strings.
2. If the length of s1 is larger than s2 then return false.
3. Iterate through the length of s1 and increment the count for each character in both s1_map and s2_map.
4. Now iterate through length of s2 - length of s1 to keep the sliding window of size s1.
5. If s1_map and s2_map are equal during the iterations, return true.
6. Otherwise, slide the window by updating the counts in s2_map.

The algorithm will return the result once the iterations are completed.

## A solution in Javascript

```javascript
function checkInclusion(s1, s2) {
    if (s1.length > s2.length) return false;
    const s1_map = new Array(26).fill(0);
    const s2_map = new Array(26).fill(0);

    for (let i = 0; i < s1.length; i++) {
        s1_map[s1.charCodeAt(i) - 'a'.charCodeAt(0)]++;
        s2_map[s2.charCodeAt(i) - 'a'.charCodeAt(0)]++;
    }

    for (let i = 0; i < s2.length - s1.length; i++) {
        if (s1_map.every((val, idx) => val === s2_map[idx])) return true;
        s2_map[s2.charCodeAt(i) - 'a'.charCodeAt(0)]--;
        s2_map[s2.charCodeAt(i + s1.length) - 'a'.charCodeAt(0)]++;
    }

    return s1_map.every((val, idx) => val === s2_map[idx]);
}
```
1. We maintain two array s1_map and s2_map to keep track of the character frequency in the respective strings.
2. If the length of s1 is larger than s2 then return false.
3. Iterate through the length of s1 and increment the count for each character in both s1_map and s2_map.
4. Now iterate through length of s2 - length of s1 to keep the sliding window of size s1.
5. If s1_map and s2_map are equal during the iterations, return true.
6. Otherwise, slide the window by updating the counts in s2_map.

The algorithm will return the result once the iterations are completed.


# Maximum Vacation Days

- slug: maximum-vacation-days
- difficulty: Hard

LeetCode wants to give one of its best employees the option to travel among `n` cities to collect algorithm problems. But all work and no play makes Jack a dull boy, you could take vacations in some particular cities and weeks. Your job is to schedule the traveling to maximize the number of vacation days you could take, but there are certain rules and restrictions you need to follow.

Rules and restrictions:

1.  You can only travel among `n` cities, represented by indexes from `0` to `n - 1`. Initially, you are in the city indexed `0` on **Monday**.
2.  The cities are connected by flights. The flights are represented as an `n x n` matrix (not necessarily symmetrical), called `flights` representing the airline status from the city `i` to the city `j`. If there is no flight from the city `i` to the city `j`, `flights[i][j] == 0`; Otherwise, `flights[i][j] == 1`. Also, `flights[i][i] == 0` for all `i`.
3.  You totally have `k` weeks (each week has **seven days**) to travel. You can only take flights at most once per day and can only take flights on each week's Monday morning. Since flight time is so short, we do not consider the impact of flight time.
4.  For each city, you can only have restricted vacation days in different weeks, given an `n x k` matrix called `days` representing this relationship. For the value of `days[i][j]`, it represents the maximum days you could take a vacation in the city `i` in the week `j`.
5.  You could stay in a city beyond the number of vacation days, but you should work on the extra days, which will not be counted as vacation days.
6.  If you fly from city `A` to city `B` and take the vacation on that day, the deduction towards vacation days will count towards the vacation days of city `B` in that week.
7.  We do not consider the impact of flight hours on the calculation of vacation days.

Given the two matrices `flights` and `days`, return _the maximum vacation days you could take during_ `k` _weeks_.

**Example 1:**

**Input:** flights = \[\[0,1,1\],\[1,0,1\],\[1,1,0\]\], days = \[\[1,3,1\],\[6,0,3\],\[3,3,3\]\]
**Output:** 12
**Explanation:**
One of the best strategies is:
1st week : fly from city 0 to city 1 on Monday, and play 6 days and work 1 day.
(Although you start at city 0, we could also fly to and start at other cities since it is Monday.)
2nd week : fly from city 1 to city 2 on Monday, and play 3 days and work 4 days.
3rd week : stay at city 2, and play 3 days and work 4 days.
Ans = 6 + 3 + 3 = 12.

**Example 2:**

**Input:** flights = \[\[0,0,0\],\[0,0,0\],\[0,0,0\]\], days = \[\[1,1,1\],\[7,7,7\],\[7,7,7\]\]
**Output:** 3
**Explanation:**
Since there are no flights that enable you to move to another city, you have to stay at city 0 for the whole 3 weeks.
For each week, you only have one day to play and six days to work.
So the maximum number of vacation days is 3.
Ans = 1 + 1 + 1 = 3.

**Example 3:**

**Input:** flights = \[\[0,1,1\],\[1,0,1\],\[1,1,0\]\], days = \[\[7,0,0\],\[0,7,0\],\[0,0,7\]\]
**Output:** 21
**Explanation:**
One of the best strategies is:
1st week : stay at city 0, and play 7 days.
2nd week : fly from city 0 to city 1 on Monday, and play 7 days.
3rd week : fly from city 1 to city 2 on Monday, and play 7 days.
Ans = 7 + 7 + 7 = 21

**Constraints:**

*   `n == flights.length`
*   `n == flights[i].length`
*   `n == days.length`
*   `k == days[i].length`
*   `1 <= n, k <= 100`
*   `flights[i][j]` is either `0` or `1`.
*   `0 <= days[i][j] <= 7`

## A solution in Java

```java
public int maxVacationDays(int[][] flights, int[][] days) {
    int n = flights.length;
    int k = days[0].length;
    int[][] memo = new int[n][k];
    for (int i = 0; i < n; i++) {
        Arrays.fill(memo[i], -1);
    }
    return dfs(flights, days, 0, 0, memo);
}

private int dfs(int[][] flights, int[][] days, int week, int city, int[][] memo) {
    int numCities = flights.length;
    int numWeeks = days[0].length;

    if (week == numWeeks) {
        return 0;
    }

    if (memo[city][week] != -1) {
        return memo[city][week];
    }

    int maxVacation = days[city][week] + dfs(flights, days, week + 1, city, memo);

    for (int i = 0; i < numCities; i++) {
        if (flights[city][i] == 1) {
            maxVacation = Math.max(maxVacation, days[i][week] + dfs(flights, days, week + 1, i, memo));
        }
    }

    memo[city][week] = maxVacation;
    return maxVacation;
}
```
We will use Depth First Search to explore all the possible valid city change and weeks, and keep track of the current week and current city.

We use memoization to store the calculated maximum vacation for each city and week, to avoid redundant calculations.

The base case is when the current week is equal to the total number of weeks, in this case, we can't take any more vacations, so we return 0.

We initialize the maximum vacation to be the vacation days in the current city and week, calling the dfs function recursively with the next week and the same city, as we don't change the city in this case.

Then, for each possible city change using the flights matrix, we calculate the maximum vacation days with the new city and update the maximum vacation accordingly.

We store the maximum vacation for the current city and week in the memoization table and return the maximum vacation.

The final result is the maximum vacation days starting from city 0 and week 0.

## A solution in C++

```cpp
int dfs(const vector<vector<int>>& flights, const vector<vector<int>>& days, int currentWeek, int currentCity, vector<vector<int>>& memo) {
    if (currentWeek == days[currentCity].size()) {
        return 0;
    }
    if (memo[currentCity][currentWeek] != -1) {
        return memo[currentCity][currentWeek];
    }

    int maxVacation = days[currentCity][currentWeek] + dfs(flights, days, currentWeek + 1, currentCity, memo);

    for (int i = 0; i < flights.size(); i++) {
        if (flights[currentCity][i] == 1) {
            maxVacation = max(maxVacation, days[i][currentWeek] + dfs(flights, days, currentWeek + 1, i, memo));
        }
    }

    memo[currentCity][currentWeek] = maxVacation;
    return maxVacation;
}

int maxVacationDays(vector<vector<int>>& flights, vector<vector<int>>& days) {
    vector<vector<int>> memo(flights.size(), vector<int>(days[0].size(), -1));
    return dfs(flights, days, 0, 0, memo);
}
```
We will use Depth First Search to explore all the possible valid city change and weeks, and keep track of the current week and current city.

We use memoization to store the calculated maximum vacation for each city and week, to avoid redundant calculations.

The base case is when the current week is equal to the total number of weeks, in this case, we can't take any more vacations, so we return 0.

We initialize the maximum vacation to be the vacation days in the current city and week, calling the dfs function recursively with the next week and the same city, as we don't change the city in this case.

Then, for each possible city change using the flights matrix, we calculate the maximum vacation days with the new city and update the maximum vacation accordingly.

We store the maximum vacation for the current city and week in the memoization table and return the maximum vacation.

The final result is the maximum vacation days starting from city 0 and week 0.

## A solution in Python

```python
def maxVacationDays(flights, days):
    n = len(flights)
    k = len(days[0])
    memo = [[-1] * k for _ in range(n)]

    def dfs(currentWeek, currentCity):
        if currentWeek == k:
            return 0
        if memo[currentCity][currentWeek] != -1:
            return memo[currentCity][currentWeek]

        maxVacation = days[currentCity][currentWeek] + dfs(currentWeek + 1, currentCity)

        for i in range(n):
            if flights[currentCity][i] == 1:
                maxVacation = max(maxVacation, days[i][currentWeek] + dfs(currentWeek + 1, i))

        memo[currentCity][currentWeek] = maxVacation
        return maxVacation

    return dfs(0, 0)
```
We will use Depth First Search to explore all the possible valid city change and weeks, and keep track of the current week and current city.

We use memoization to store the calculated maximum vacation for each city and week, to avoid redundant calculations.

The base case is when the current week is equal to the total number of weeks, in this case, we can't take any more vacations, so we return 0.

We initialize the maximum vacation to be the vacation days in the current city and week, calling the dfs function recursively with the next week and the same city, as we don't change the city in this case.

Then, for each possible city change using the flights matrix, we calculate the maximum vacation days with the new city and update the maximum vacation accordingly.

We store the maximum vacation for the current city and week in the memoization table and return the maximum vacation.

The final result is the maximum vacation days starting from city 0 and week 0.

## A solution in Javascript

```javascript
function maxVacationDays(flights, days) {
    let n = flights.length;
    let k = days[0].length;
    let memo = new Array(n).fill(null).map(() => new Array(k).fill(-1));

    function dfs(week, city) {
        if (week === k) {
            return 0;
        }
        if (memo[city][week] !== -1) {
            return memo[city][week];
        }

        let maxVacation = days[city][week] + dfs(week + 1, city);

        for (let i = 0; i < n; i++) {
            if (flights[city][i] === 1) {
                maxVacation = Math.max(maxVacation, days[i][week] + dfs(week + 1, i));
            }
        }

        memo[city][week] = maxVacation;
        return maxVacation;
    }

    return dfs(0, 0);
}
```
We will use Depth First Search to explore all the possible valid city change and weeks, and keep track of the current week and current city.

We use memoization to store the calculated maximum vacation for each city and week, to avoid redundant calculations.

The base case is when the current week is equal to the total number of weeks, in this case, we can't take any more vacations, so we return 0.

We initialize the maximum vacation to be the vacation days in the current city and week, calling the dfs function recursively with the next week and the same city, as we don't change the city in this case.

Then, for each possible city change using the flights matrix, we calculate the maximum vacation days with the new city and update the maximum vacation accordingly.

We store the maximum vacation for the current city and week in the memoization table and return the maximum vacation.

The final result is the maximum vacation days starting from city 0 and week 0.


# Subtree of Another Tree

- slug: subtree-of-another-tree
- difficulty: Easy

Given the roots of two binary trees `root` and `subRoot`, return `true` if there is a subtree of `root` with the same structure and node values of `subRoot` and `false` otherwise.

A subtree of a binary tree `tree` is a tree that consists of a node in `tree` and all of this node's descendants. The tree `tree` could also be considered as a subtree of itself.

**Example 1:**

**Input:** root = \[3,4,5,1,2\], subRoot = \[4,1,2\]
**Output:** true

**Example 2:**

**Input:** root = \[3,4,5,1,2,null,null,null,null,0\], subRoot = \[4,1,2\]
**Output:** false

**Constraints:**

*   The number of nodes in the `root` tree is in the range `[1, 2000]`.
*   The number of nodes in the `subRoot` tree is in the range `[1, 1000]`.
*   `-104 <= root.val <= 104`
*   `-104 <= subRoot.val <= 104`

## A solution in Java

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

public boolean isSubtree(TreeNode root, TreeNode subRoot) {
    if (root == null) return false;
    if (isIdentical(root, subRoot)) return true;
    return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}

public boolean isIdentical(TreeNode n1, TreeNode n2) {
    if (n1 == null || n2 == null) return n1 == n2;
    if (n1.val != n2.val) return false;
    return isIdentical(n1.left, n2.left) && isIdentical(n1.right, n2.right);
}
```
The algorithm checks if `subRoot` is a subtree of `root` by first looking whether the two trees have the same root node. If they do, it checks whether the substructures are also identical. If they are not, then `subRoot` is not a subtree at this level, and the algorithm looks further down the left and right branches of `root`. This is done by returning the logical `OR` between the result of checking left and right branches.

The helper function `isIdentical` checks whether the two given trees have the same structure and node values, by comparing the current nodes and then recursively traversing the left and right substructures. If a `None` value for a node is found, the two nodes are identical if they are both `None`. Otherwise, if the node values differ, the trees are not identical.

## A solution in C++

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

bool isSubtree(TreeNode* root, TreeNode* subRoot) {
    if (root == nullptr) return false;
    if (isIdentical(root, subRoot)) return true;
    return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}

bool isIdentical(TreeNode* n1, TreeNode* n2) {
    if (n1 == nullptr || n2 == nullptr) return n1 == n2;
    if (n1->val != n2->val) return false;
    return isIdentical(n1->left, n2->left) && isIdentical(n1->right, n2->right);
}
```
The algorithm checks if `subRoot` is a subtree of `root` by first looking whether the two trees have the same root node. If they do, it checks whether the substructures are also identical. If they are not, then `subRoot` is not a subtree at this level, and the algorithm looks further down the left and right branches of `root`. This is done by returning the logical `OR` between the result of checking left and right branches.

The helper function `isIdentical` checks whether the two given trees have the same structure and node values, by comparing the current nodes and then recursively traversing the left and right substructures. If a `None` value for a node is found, the two nodes are identical if they are both `None`. Otherwise, if the node values differ, the trees are not identical.

## A solution in Python

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

function isSubtree(root, subRoot) {
    if (root === null) return false;
    if (isIdentical(root, subRoot)) return true;
    return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}

function isIdentical(n1, n2) {
    if (n1 === null || n2 === null) return n1 === n2;
    if (n1.val !== n2.val) return false;
    return isIdentical(n1.left, n2.left) && isIdentical(n1.right, n2.right);
}
```
The algorithm checks if `subRoot` is a subtree of `root` by first looking whether the two trees have the same root node. If they do, it checks whether the substructures are also identical. If they are not, then `subRoot` is not a subtree at this level, and the algorithm looks further down the left and right branches of `root`. This is done by returning the logical `OR` between the result of checking left and right branches.

The helper function `isIdentical` checks whether the two given trees have the same structure and node values, by comparing the current nodes and then recursively traversing the left and right substructures. If a `None` value for a node is found, the two nodes are identical if they are both `None`. Otherwise, if the node values differ, the trees are not identical.

## A solution in Javascript

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

def isSubtree(root, subRoot):
    if root is None:
        return False
    if is_identical(root, subRoot):
        return True
    return isSubtree(root.left, subRoot) or isSubtree(root.right, subRoot)

def is_identical(n1, n2):
    if n1 is None or n2 is None:
        return n1 == n2
    if n1.val != n2.val:
        return False
    return is_identical(n1.left, n2.left) and is_identical(n1.right, n2.right)
```
The algorithm checks if `subRoot` is a subtree of `root` by first looking whether the two trees have the same root node. If they do, it checks whether the substructures are also identical. If they are not, then `subRoot` is not a subtree at this level, and the algorithm looks further down the left and right branches of `root`. This is done by returning the logical `OR` between the result of checking left and right branches.

The helper function `isIdentical` checks whether the two given trees have the same structure and node values, by comparing the current nodes and then recursively traversing the left and right substructures. If a `None` value for a node is found, the two nodes are identical if they are both `None`. Otherwise, if the node values differ, the trees are not identical.


# Squirrel Simulation

- slug: squirrel-simulation
- difficulty: Medium

You are given two integers `height` and `width` representing a garden of size `height x width`. You are also given:

*   an array `tree` where `tree = [treer, treec]` is the position of the tree in the garden,
*   an array `squirrel` where `squirrel = [squirrelr, squirrelc]` is the position of the squirrel in the garden,
*   and an array `nuts` where `nuts[i] = [nutir, nutic]` is the position of the `ith` nut in the garden.

The squirrel can only take at most one nut at one time and can move in four directions: up, down, left, and right, to the adjacent cell.

Return _the **minimal distance** for the squirrel to collect all the nuts and put them under the tree one by one_.

The **distance** is the number of moves.

**Example 1:**

**Input:** height = 5, width = 7, tree = \[2,2\], squirrel = \[4,4\], nuts = \[\[3,0\], \[2,5\]\]
**Output:** 12
**Explanation:** The squirrel should go to the nut at \[2, 5\] first to achieve a minimal distance.

**Example 2:**

**Input:** height = 1, width = 3, tree = \[0,1\], squirrel = \[0,0\], nuts = \[\[0,2\]\]
**Output:** 3

**Constraints:**

*   `1 <= height, width <= 100`
*   `tree.length == 2`
*   `squirrel.length == 2`
*   `1 <= nuts.length <= 5000`
*   `nuts[i].length == 2`
*   `0 <= treer, squirrelr, nutir <= height`
*   `0 <= treec, squirrelc, nutic <= width`

## A solution in Java

```java
public int minDistance(int height, int width, int[] tree, int[] squirrel, int[][] nuts) {
    int totalDist = 0;
    int minDiff = Integer.MAX_VALUE;

    for (int[] nut : nuts) {
        int treeDist = Math.abs(tree[0] - nut[0]) + Math.abs(tree[1] - nut[1]);
        int squirrelDist = Math.abs(squirrel[0] - nut[0]) + Math.abs(squirrel[1] - nut[1]);

        totalDist += 2 * treeDist;
        minDiff = Math.min(minDiff, squirrelDist - treeDist);
    }

    return totalDist + minDiff;
}
```
Our main goal in this problem is to minimize the total distance. We will loop through all the nuts and calculate the distance between the squirrel and the nut, and the distance between the tree and the nut. We have to double the tree distance due to the squirrel having to come back to the tree. After calculating the distances, we subtract the tree distance from the squirrel distance and find the minimum difference. The total distance is the sum of all the doubled tree distances and the minimum difference.

## A solution in C++

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

int minDistance(int height, int width, vector<int>& tree, vector<int>& squirrel, vector<vector<int>>& nuts) {
    int totalDist = 0;
    int minDiff = INT_MAX;

    for (vector<int>& nut : nuts) {
        int treeDist = abs(tree[0] - nut[0]) + abs(tree[1] - nut[1]);
        int squirrelDist = abs(squirrel[0] - nut[0]) + abs(squirrel[1] - nut[1]);

        totalDist += 2 * treeDist;
        minDiff = min(minDiff, squirrelDist - treeDist);
    }

    return totalDist + minDiff;
}
```
Our main goal in this problem is to minimize the total distance. We will loop through all the nuts and calculate the distance between the squirrel and the nut, and the distance between the tree and the nut. We have to double the tree distance due to the squirrel having to come back to the tree. After calculating the distances, we subtract the tree distance from the squirrel distance and find the minimum difference. The total distance is the sum of all the doubled tree distances and the minimum difference.

## A solution in Python

```python
def minDistance(height, width, tree, squirrel, nuts):
    totalDist = 0
    minDiff = float("inf")

    for nut in nuts:
        treeDist = abs(tree[0] - nut[0]) + abs(tree[1] - nut[1])
        squirrelDist = abs(squirrel[0] - nut[0]) + abs(squirrel[1] - nut[1])

        totalDist += 2 * treeDist
        minDiff = min(minDiff, squirrelDist - treeDist)

    return totalDist + minDiff
```
Our main goal in this problem is to minimize the total distance. We will loop through all the nuts and calculate the distance between the squirrel and the nut, and the distance between the tree and the nut. We have to double the tree distance due to the squirrel having to come back to the tree. After calculating the distances, we subtract the tree distance from the squirrel distance and find the minimum difference. The total distance is the sum of all the doubled tree distances and the minimum difference.

## A solution in Javascript

```javascript
function minDistance(height, width, tree, squirrel, nuts) {
    let totalDist = 0;
    let minDiff = Infinity;

    for (let nut of nuts) {
        let treeDist = Math.abs(tree[0] - nut[0]) + Math.abs(tree[1] - nut[1]);
        let squirrelDist = Math.abs(squirrel[0] - nut[0]) + Math.abs(squirrel[1] - nut[1]);

        totalDist += 2 * treeDist;
        minDiff = Math.min(minDiff, squirrelDist - treeDist);
    }

    return totalDist + minDiff;
}
```
Our main goal in this problem is to minimize the total distance. We will loop through all the nuts and calculate the distance between the squirrel and the nut, and the distance between the tree and the nut. We have to double the tree distance due to the squirrel having to come back to the tree. After calculating the distances, we subtract the tree distance from the squirrel distance and find the minimum difference. The total distance is the sum of all the doubled tree distances and the minimum difference.