# Sliding Window Maximum

- slug: sliding-window-maximum
- difficulty: Hard

You are given an array of integers `nums`, there is a sliding window of size `k` which is moving from the very left of the array to the very right. You can only see the `k` numbers in the window. Each time the sliding window moves right by one position.

Return _the max sliding window_.

**Example 1:**

**Input:** nums = \[1,3,-1,-3,5,3,6,7\], k = 3
**Output:** \[3,3,5,5,6,7\]
**Explanation:**
Window position                Max
---------------               -----
\[1  3  -1\] -3  5  3  6  7       **3**
 1 \[3  -1  -3\] 5  3  6  7       **3**
 1  3 \[-1  -3  5\] 3  6  7      ** 5**
 1  3  -1 \[-3  5  3\] 6  7       **5**
 1  3  -1  -3 \[5  3  6\] 7       **6**
 1  3  -1  -3  5 \[3  6  7\]      **7**

**Example 2:**

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

**Constraints:**

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

## A solution in Java

```java
import java.util.LinkedList;
import java.util.Deque;

public int[] maxSlidingWindow(int[] nums, int k) {
    if (nums == null || nums.length == 0) return new int[0];
    int[] result = new int[nums.length - k + 1];
    int idx = 0;
    Deque<Integer> deque = new LinkedList<Integer>();

    for (int i = 0; i < nums.length; i++) {
        if (!deque.isEmpty() && deque.peekFirst() == i - k) deque.poll();

        while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
            deque.removeLast();
        }

        deque.offer(i);
        if (i >= k - 1) {
            result[idx++] = nums[deque.peek()];
        }
    }
    return result;
}
```
1. Create an empty deque (double-ended queue) and an empty results list.
2. Iterate through the given array.
3. Remove the elements that are out of the current window from the front of the deque.
4. Remove the elements that are smaller than the current element from the back of the deque.
5. Push the current index into the deque.
6. If the current index is greater than or equal to k-1 (window size), add the front element of deque into the results list.
7. Return the results list after iterating through the entire array.

The deque will keep track of the indices of the maximum elements in the current window. At each step, the first element in the deque will be the index of the maximum element in the current window.

## A solution in C++

```cpp
#include <vector>
#include <deque>

std::vector<int> maxSlidingWindow(std::vector<int>& nums, int k) {
    std::vector<int> result;
    std::deque<int> dq;

    for (int i = 0; i < nums.size(); i++) {
        while (!dq.empty() && dq.front() < i - k + 1) {
            dq.pop_front();
        }

        while (!dq.empty() && nums[dq.back()] < nums[i]) {
            dq.pop_back();
        }

        dq.push_back(i);

        if (i >= k - 1) {
            result.push_back(nums[dq.front()]);
        }
    }

    return result;
}
```
1. Create an empty deque (double-ended queue) and an empty results list.
2. Iterate through the given array.
3. Remove the elements that are out of the current window from the front of the deque.
4. Remove the elements that are smaller than the current element from the back of the deque.
5. Push the current index into the deque.
6. If the current index is greater than or equal to k-1 (window size), add the front element of deque into the results list.
7. Return the results list after iterating through the entire array.

The deque will keep track of the indices of the maximum elements in the current window. At each step, the first element in the deque will be the index of the maximum element in the current window.

## A solution in Python

```python
from collections import deque

def maxSlidingWindow(nums, k):
    dq = deque()
    result = []

    for i in range(len(nums)):
        while dq and dq[0] < i - k + 1:
            dq.popleft()

        while dq and nums[dq[-1]] < nums[i]:
            dq.pop()

        dq.append(i)

        if i >= k - 1:
            result.append(nums[dq[0]])

    return result
```
1. Create an empty deque (double-ended queue) and an empty results list.
2. Iterate through the given array.
3. Remove the elements that are out of the current window from the front of the deque.
4. Remove the elements that are smaller than the current element from the back of the deque.
5. Push the current index into the deque.
6. If the current index is greater than or equal to k-1 (window size), add the front element of deque into the results list.
7. Return the results list after iterating through the entire array.

The deque will keep track of the indices of the maximum elements in the current window. At each step, the first element in the deque will be the index of the maximum element in the current window.

## A solution in Javascript

```javascript
function maxSlidingWindow(nums, k) {
  let result = [];
  let dq = [];

  for (let i = 0; i < nums.length; i++) {
    while (dq.length && dq[0] < i - k + 1) {
      dq.shift();
    }

    while (dq.length && nums[dq[dq.length - 1]] < nums[i]) {
      dq.pop();
    }

    dq.push(i);

    if (i >= k - 1) {
      result.push(nums[dq[0]]);
    }
  }

  return result;
}
```
1. Create an empty deque (double-ended queue) and an empty results list.
2. Iterate through the given array.
3. Remove the elements that are out of the current window from the front of the deque.
4. Remove the elements that are smaller than the current element from the back of the deque.
5. Push the current index into the deque.
6. If the current index is greater than or equal to k-1 (window size), add the front element of deque into the results list.
7. Return the results list after iterating through the entire array.

The deque will keep track of the indices of the maximum elements in the current window. At each step, the first element in the deque will be the index of the maximum element in the current window.


# Search a 2D Matrix II

- slug: search-a-2d-matrix-ii
- difficulty: Medium

Write an efficient algorithm that searches for a value `target` in an `m x n` integer matrix `matrix`. This matrix has the following properties:

*   Integers in each row are sorted in ascending from left to right.
*   Integers in each column are sorted in ascending from top to bottom.

**Example 1:**

**Input:** matrix = \[\[1,4,7,11,15\],\[2,5,8,12,19\],\[3,6,9,16,22\],\[10,13,14,17,24\],\[18,21,23,26,30\]\], target = 5
**Output:** true

**Example 2:**

**Input:** matrix = \[\[1,4,7,11,15\],\[2,5,8,12,19\],\[3,6,9,16,22\],\[10,13,14,17,24\],\[18,21,23,26,30\]\], target = 20
**Output:** false

**Constraints:**

*   `m == matrix.length`
*   `n == matrix[i].length`
*   `1 <= n, m <= 300`
*   `-109 <= matrix[i][j] <= 109`
*   All the integers in each row are **sorted** in ascending order.
*   All the integers in each column are **sorted** in ascending order.
*   `-109 <= target <= 109`

## A solution in Java

```java
public boolean searchMatrix(int[][] matrix, int target) {
    int row = matrix.length - 1, col = 0;
    while (row >= 0 && col < matrix[0].length) {
        if (matrix[row][col] > target) {
            row--;
        } else if (matrix[row][col] < target) {
            col++;
        } else {
            return true;
        }
    }
    return false;
}
```
The algorithm starts at the bottom-left corner of the matrix. Then it follows these rules:
1. If the current value is bigger than the target, then move up in the matrix (because all values above will be smaller).
2. If the current value is smaller than the target, then move to the right in the matrix (because all values to the right will be bigger).
3. If the current value is equal to the target, return true.

This algorithm is efficient as it reduces the search space in every step by either eliminating a row or a column. At most, it will take m + n steps.

## A solution in C++

```cpp
bool searchMatrix(vector<vector<int>>& matrix, int target) {
    int row = matrix.size() - 1, col = 0;
    while (row >= 0 && col < matrix[0].size()) {
        if (matrix[row][col] > target) {
            row--;
        } else if (matrix[row][col] < target) {
            col++;
        } else {
            return true;
        }
    }
    return false;
}
```
The algorithm starts at the bottom-left corner of the matrix. Then it follows these rules:
1. If the current value is bigger than the target, then move up in the matrix (because all values above will be smaller).
2. If the current value is smaller than the target, then move to the right in the matrix (because all values to the right will be bigger).
3. If the current value is equal to the target, return true.

This algorithm is efficient as it reduces the search space in every step by either eliminating a row or a column. At most, it will take m + n steps.

## A solution in Python

```python
def searchMatrix(matrix, target):
    row, col = len(matrix) - 1, 0
    while row >= 0 and col < len(matrix[0]):
        if matrix[row][col] > target:
            row -= 1
        elif matrix[row][col] < target:
            col += 1
        else:
            return True
    return False
```
The algorithm starts at the bottom-left corner of the matrix. Then it follows these rules:
1. If the current value is bigger than the target, then move up in the matrix (because all values above will be smaller).
2. If the current value is smaller than the target, then move to the right in the matrix (because all values to the right will be bigger).
3. If the current value is equal to the target, return true.

This algorithm is efficient as it reduces the search space in every step by either eliminating a row or a column. At most, it will take m + n steps.

## A solution in Javascript

```javascript
function searchMatrix(matrix, target) {
    let row = matrix.length - 1, col = 0;
    while(row >= 0 && col < matrix[0].length) {
        if(matrix[row][col] > target) {
            row--;
        } else if(matrix[row][col] < target) {
            col++;
        } else {
            return true;
        }
    }
    return false;
}
```
The algorithm starts at the bottom-left corner of the matrix. Then it follows these rules:
1. If the current value is bigger than the target, then move up in the matrix (because all values above will be smaller).
2. If the current value is smaller than the target, then move to the right in the matrix (because all values to the right will be bigger).
3. If the current value is equal to the target, return true.

This algorithm is efficient as it reduces the search space in every step by either eliminating a row or a column. At most, it will take m + n steps.


# Different Ways to Add Parentheses

- slug: different-ways-to-add-parentheses
- difficulty: Medium

Given a string `expression` of numbers and operators, return _all possible results from computing all the different possible ways to group numbers and operators_. You may return the answer in **any order**.

The test cases are generated such that the output values fit in a 32-bit integer and the number of different results does not exceed `104`.

**Example 1:**

**Input:** expression =  "2-1-1 "
**Output:** \[0,2\]
**Explanation:**
((2-1)-1) = 0
(2-(1-1)) = 2

**Example 2:**

**Input:** expression =  "2\*3-4\*5 "
**Output:** \[-34,-14,-10,-10,10\]
**Explanation:**
(2\*(3-(4\*5))) = -34
((2\*3)-(4\*5)) = -14
((2\*(3-4))\*5) = -10
(2\*((3-4)\*5)) = -10
(((2\*3)-4)\*5) = 10

**Constraints:**

*   `1 <= expression.length <= 20`
*   `expression` consists of digits and the operator `'+'`, `'-'`, and `'*'`.
*   All the integer values in the input expression are in the range `[0, 99]`.

## A solution in Java

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

public List<Integer> diffWaysToCompute(String input) {
    List<Integer> result = new ArrayList<>();
    for (int i = 0; i < input.length(); i++) {
        char c = input.charAt(i);
        if (c == '+' || c == '-' || c == '*') {
            List<Integer> left = diffWaysToCompute(input.substring(0, i));
            List<Integer> right = diffWaysToCompute(input.substring(i + 1));
            for (int l : left) {
                for (int r : right) {
                    if (c == '+') result.add(l + r);
                    else if (c == '-') result.add(l - r);
                    else if (c == '*') result.add(l * r);
                }
            }
        }
    }
    if (result.isEmpty()) result.add(Integer.parseInt(input));
    return result;
}
```
The algorithm is a recursive divide-and-conquer approach. It starts by iterating through the `input` string and looks for operators (+, -, *). When an operator is found, the problem is divided into two sub-problems: left and right. These sub-problems are independently solved through recursively calling the `diffWaysToCompute` function with corresponding substrings.

Each recursion returns a list of possible results for each sub-problem. For each operator, we combine these results by iterating through both lists and performing the corresponding operation (addition, subtraction, or multiplication).

If no operators are present in the input string, a base case is reached, and the current number in the input string is returned as the only result. The recursion ultimately produces a list of all possible results for the original expression by combining results from all sub-problems.

## A solution in C++

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

using namespace std;

vector<int> diffWaysToCompute(string input) {
    vector<int> result;
    for (int i = 0; i < input.size(); i++) {
        char c = input[i];
        if (c == '+' || c == '-' || c == '*') {
            auto left = diffWaysToCompute(input.substr(0, i));
            auto right = diffWaysToCompute(input.substr(i + 1));
            for (int l : left) {
                for (int r : right) {
                    if (c == '+') result.push_back(l + r);
                    else if (c == '-') result.push_back(l - r);
                    else if (c == '*') result.push_back(l * r);
                }
            }
        }
    }
    if (result.empty()) result.push_back(stoi(input));
    return result;
}
```
The algorithm is a recursive divide-and-conquer approach. It starts by iterating through the `input` string and looks for operators (+, -, *). When an operator is found, the problem is divided into two sub-problems: left and right. These sub-problems are independently solved through recursively calling the `diffWaysToCompute` function with corresponding substrings.

Each recursion returns a list of possible results for each sub-problem. For each operator, we combine these results by iterating through both lists and performing the corresponding operation (addition, subtraction, or multiplication).

If no operators are present in the input string, a base case is reached, and the current number in the input string is returned as the only result. The recursion ultimately produces a list of all possible results for the original expression by combining results from all sub-problems.

## A solution in Python

```python
def diffWaysToCompute(input: str):
    result = []
    for i in range(len(input)):
        c = input[i]
        if c == '+' or c == '-' or c == '*':
            left = diffWaysToCompute(input[:i])
            right = diffWaysToCompute(input[i + 1:])
            for l in left:
                for r in right:
                    if c == '+': result.append(l + r)
                    elif c == '-': result.append(l - r)
                    elif c == '*': result.append(l * r)
    if not result:
        result.append(int(input))
    return result
```
The algorithm is a recursive divide-and-conquer approach. It starts by iterating through the `input` string and looks for operators (+, -, *). When an operator is found, the problem is divided into two sub-problems: left and right. These sub-problems are independently solved through recursively calling the `diffWaysToCompute` function with corresponding substrings.

Each recursion returns a list of possible results for each sub-problem. For each operator, we combine these results by iterating through both lists and performing the corresponding operation (addition, subtraction, or multiplication).

If no operators are present in the input string, a base case is reached, and the current number in the input string is returned as the only result. The recursion ultimately produces a list of all possible results for the original expression by combining results from all sub-problems.

## A solution in Javascript

```javascript
function diffWaysToCompute(input) {
    const result = [];
    for (let i = 0; i < input.length; i++) {
        const c = input[i];
        if (c === '+' || c === '-' || c === '*') {
            const left = diffWaysToCompute(input.slice(0, i));
            const right = diffWaysToCompute(input.slice(i + 1));
            for (const l of left) {
                for (const r of right) {
                    if (c === '+') result.push(l + r);
                    else if (c === '-') result.push(l - r);
                    else if (c === '*') result.push(l * r);
                }
            }
        }
    }
    if (result.length === 0) result.push(parseInt(input));
    return result;
}
```
The algorithm is a recursive divide-and-conquer approach. It starts by iterating through the `input` string and looks for operators (+, -, *). When an operator is found, the problem is divided into two sub-problems: left and right. These sub-problems are independently solved through recursively calling the `diffWaysToCompute` function with corresponding substrings.

Each recursion returns a list of possible results for each sub-problem. For each operator, we combine these results by iterating through both lists and performing the corresponding operation (addition, subtraction, or multiplication).

If no operators are present in the input string, a base case is reached, and the current number in the input string is returned as the only result. The recursion ultimately produces a list of all possible results for the original expression by combining results from all sub-problems.


# Valid Anagram

- slug: valid-anagram
- difficulty: Easy

Given two strings `s` and `t`, return `true` _if_ `t` _is an anagram of_ `s`_, and_ `false` _otherwise_.

An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

**Example 1:**

**Input:** s = "anagram", t = "nagaram"
**Output:** true

**Example 2:**

**Input:** s = "rat", t = "car"
**Output:** false

**Constraints:**

*   `1 <= s.length, t.length <= 5 * 104`
*   `s` and `t` consist of lowercase English letters.

**Follow up:** What if the inputs contain Unicode characters? How would you adapt your solution to such a case?

## A solution in Java

```java
public boolean isAnagram(String s, String t) {
    if(s.length() != t.length())
        return false;

    int[] counts = new int[26];
    for(char c : s.toCharArray())
        counts[c - 'a']++;

    for(char c : t.toCharArray()) {
        if(counts[c - 'a'] == 0)
            return false;
        counts[c - 'a']--;
    }

    return true;
}
```
The algorithm first checks if the two input strings have the same length. If they do not, it returns `false`, because an anagram of a string would have the same length as the original string.

Then, the algorithm initializes a hash table to store the frequency of each character in the string `s`. It iterates through the string `s`, and for each character, it increments the corresponding frequency count in the hash table.

It then iterates through the string `t`. For each character in `t`, it checks if the frequency count of that character in the hash table is greater than 0. If it is not, that means the character either wasn't in the string `s`, or has been used up already, so the function returns `false`. Otherwise, it decrements the frequency count for the current character in the hash table.

Finally, if the function has not yet returned `false`, that means that the two strings are anagrams and the function returns `true`.

## A solution in C++

```cpp
bool isAnagram(std::string s, std::string t) {
    if(s.size() != t.size())
        return false;

    std::unordered_map<char, int> counts;
    for(char c : s)
        counts[c]++;

    for(char c : t) {
        if(counts[c] == 0)
            return false;
        counts[c]--;
    }

    return true;
}
```
The algorithm first checks if the two input strings have the same length. If they do not, it returns `false`, because an anagram of a string would have the same length as the original string.

Then, the algorithm initializes a hash table to store the frequency of each character in the string `s`. It iterates through the string `s`, and for each character, it increments the corresponding frequency count in the hash table.

It then iterates through the string `t`. For each character in `t`, it checks if the frequency count of that character in the hash table is greater than 0. If it is not, that means the character either wasn't in the string `s`, or has been used up already, so the function returns `false`. Otherwise, it decrements the frequency count for the current character in the hash table.

Finally, if the function has not yet returned `false`, that means that the two strings are anagrams and the function returns `true`.

## A solution in Python

```python
def is_anagram(s, t):
    if len(s) != len(t):
        return False

    counts = {}
    for c in s:
        if c in counts:
            counts[c] += 1
        else:
            counts[c] = 1

    for c in t:
        if c not in counts or counts[c] == 0:
            return False
        counts[c] -= 1

    return True
```
The algorithm first checks if the two input strings have the same length. If they do not, it returns `false`, because an anagram of a string would have the same length as the original string.

Then, the algorithm initializes a hash table to store the frequency of each character in the string `s`. It iterates through the string `s`, and for each character, it increments the corresponding frequency count in the hash table.

It then iterates through the string `t`. For each character in `t`, it checks if the frequency count of that character in the hash table is greater than 0. If it is not, that means the character either wasn't in the string `s`, or has been used up already, so the function returns `false`. Otherwise, it decrements the frequency count for the current character in the hash table.

Finally, if the function has not yet returned `false`, that means that the two strings are anagrams and the function returns `true`.

## A solution in Javascript

```javascript
function isAnagram(s, t) {
    if (s.length !== t.length)
        return false;

    const counts = {};
    for (let c of s)
        counts[c] = (counts[c] || 0) + 1;

    for (let c of t) {
        if (counts[c] === 0 || !counts[c])
            return false;
        counts[c]--;
    }

    return true;
}
```
The algorithm first checks if the two input strings have the same length. If they do not, it returns `false`, because an anagram of a string would have the same length as the original string.

Then, the algorithm initializes a hash table to store the frequency of each character in the string `s`. It iterates through the string `s`, and for each character, it increments the corresponding frequency count in the hash table.

It then iterates through the string `t`. For each character in `t`, it checks if the frequency count of that character in the hash table is greater than 0. If it is not, that means the character either wasn't in the string `s`, or has been used up already, so the function returns `false`. Otherwise, it decrements the frequency count for the current character in the hash table.

Finally, if the function has not yet returned `false`, that means that the two strings are anagrams and the function returns `true`.


# Shortest Word Distance

- slug: shortest-word-distance
- difficulty: Easy

Given an array of strings `wordsDict` and two different strings that already exist in the array `word1` and `word2`, return _the shortest distance between these two words in the list_.

**Example 1:**

**Input:** wordsDict = \[ "practice ",  "makes ",  "perfect ",  "coding ",  "makes "\], word1 =  "coding ", word2 =  "practice "
**Output:** 3

**Example 2:**

**Input:** wordsDict = \[ "practice ",  "makes ",  "perfect ",  "coding ",  "makes "\], word1 =  "makes ", word2 =  "coding "
**Output:** 1

**Constraints:**

*   `2 <= wordsDict.length <= 3 * 104`
*   `1 <= wordsDict[i].length <= 10`
*   `wordsDict[i]` consists of lowercase English letters.
*   `word1` and `word2` are in `wordsDict`.
*   `word1 != word2`

## A solution in Java

```java
public int shortestDistance(String[] wordsDict, String word1, String word2) {
    int idx1 = -1, idx2 = -1, minDistance = Integer.MAX_VALUE;
    for (int i = 0; i < wordsDict.length; i++) {
        if (word1.equals(wordsDict[i])) idx1 = i;
        if (word2.equals(wordsDict[i])) idx2 = i;
        if (idx1 != -1 && idx2 != -1)
            minDistance = Math.min(minDistance, Math.abs(idx1 - idx2));
    }
    return minDistance;
}
```
The algorithm iterates through the `wordsDict` list and uses two variables `idx1` and `idx2` to store the indices of the occurrences of `word1` and `word2`. Initially, both indices are set to `-1`. In each iteration, if `word1` or `word2` is found, the corresponding index variable will be updated to store the current index.

After each index update, we check if both indices are not `-1`. If both indices are valid, the difference between the indices is computed, and `minDistance` is updated with the minimum value between the previously-stored minimum distance and the new distance.

Finally, the algorithm returns the value of `minDistance`, which represents the shortest distance between `word1` and `word2` in the `wordsDict` list.

## A solution in C++

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

int shortestDistance(std::vector<std::string> wordsDict, std::string word1, std::string word2) {
    int idx1 = -1, idx2 = -1, minDistance = INT_MAX;
    for (int i = 0; i < wordsDict.size(); i++) {
        if (wordsDict[i] == word1) idx1 = i;
        if (wordsDict[i] == word2) idx2 = i;
        if (idx1 != -1 && idx2 != -1)
            minDistance = std::min(minDistance, std::abs(idx1 - idx2));
    }
    return minDistance;
}
```
The algorithm iterates through the `wordsDict` list and uses two variables `idx1` and `idx2` to store the indices of the occurrences of `word1` and `word2`. Initially, both indices are set to `-1`. In each iteration, if `word1` or `word2` is found, the corresponding index variable will be updated to store the current index.

After each index update, we check if both indices are not `-1`. If both indices are valid, the difference between the indices is computed, and `minDistance` is updated with the minimum value between the previously-stored minimum distance and the new distance.

Finally, the algorithm returns the value of `minDistance`, which represents the shortest distance between `word1` and `word2` in the `wordsDict` list.

## A solution in Python

```python
def shortestDistance(wordsDict, word1, word2):
    idx1, idx2, minDistance = -1, -1, float('inf')
    for i, word in enumerate(wordsDict):
        if word == word1:
            idx1 = i
        if word == word2:
            idx2 = i
        if idx1 != -1 and idx2 != -1:
            minDistance = min(minDistance, abs(idx1 - idx2))
    return minDistance
```
The algorithm iterates through the `wordsDict` list and uses two variables `idx1` and `idx2` to store the indices of the occurrences of `word1` and `word2`. Initially, both indices are set to `-1`. In each iteration, if `word1` or `word2` is found, the corresponding index variable will be updated to store the current index.

After each index update, we check if both indices are not `-1`. If both indices are valid, the difference between the indices is computed, and `minDistance` is updated with the minimum value between the previously-stored minimum distance and the new distance.

Finally, the algorithm returns the value of `minDistance`, which represents the shortest distance between `word1` and `word2` in the `wordsDict` list.

## A solution in Javascript

```javascript
function shortestDistance(wordsDict, word1, word2) {
    let idx1 = -1, idx2 = -1, minDistance = Number.MAX_VALUE;
    for (let i = 0; i < wordsDict.length; i++) {
        if (wordsDict[i] === word1) idx1 = i;
        if (wordsDict[i] === word2) idx2 = i;
        if (idx1 !== -1 && idx2 !== -1)
            minDistance = Math.min(minDistance, Math.abs(idx1 - idx2));
    }
    return minDistance;
}
```
The algorithm iterates through the `wordsDict` list and uses two variables `idx1` and `idx2` to store the indices of the occurrences of `word1` and `word2`. Initially, both indices are set to `-1`. In each iteration, if `word1` or `word2` is found, the corresponding index variable will be updated to store the current index.

After each index update, we check if both indices are not `-1`. If both indices are valid, the difference between the indices is computed, and `minDistance` is updated with the minimum value between the previously-stored minimum distance and the new distance.

Finally, the algorithm returns the value of `minDistance`, which represents the shortest distance between `word1` and `word2` in the `wordsDict` list.


# Shortest Word Distance II

- slug: shortest-word-distance-ii
- difficulty: Medium

Design a data structure that will be initialized with a string array, and then it should answer queries of the shortest distance between two different strings from the array.

Implement the `WordDistance` class:

*   `WordDistance(String[] wordsDict)` initializes the object with the strings array `wordsDict`.
*   `int shortest(String word1, String word2)` returns the shortest distance between `word1` and `word2` in the array `wordsDict`.

**Example 1:**

**Input**
\[ "WordDistance ",  "shortest ",  "shortest "\]
\[\[\[ "practice ",  "makes ",  "perfect ",  "coding ",  "makes "\]\], \[ "coding ",  "practice "\], \[ "makes ",  "coding "\]\]
**Output**
\[null, 3, 1\]

**Explanation**
WordDistance wordDistance = new WordDistance(\[ "practice ",  "makes ",  "perfect ",  "coding ",  "makes "\]);
wordDistance.shortest( "coding ",  "practice "); // return 3
wordDistance.shortest( "makes ",  "coding ");    // return 1

**Constraints:**

*   `1 <= wordsDict.length <= 3 * 104`
*   `1 <= wordsDict[i].length <= 10`
*   `wordsDict[i]` consists of lowercase English letters.
*   `word1` and `word2` are in `wordsDict`.
*   `word1 != word2`
*   At most `5000` calls will be made to `shortest`.

## A solution in Java

```java
import java.util.HashMap;
import java.util.ArrayList;

class WordDistance {
    HashMap<String, ArrayList<Integer>> wordIndexes;

    public WordDistance(String[] wordsDict) {
        wordIndexes = new HashMap<>();
        for (int i = 0; i < wordsDict.length; ++i) {
            if (!wordIndexes.containsKey(wordsDict[i])) {
                wordIndexes.put(wordsDict[i], new ArrayList<>());
            }
            wordIndexes.get(wordsDict[i]).add(i);
        }
    }

    public int shortest(String word1, String word2) {
        ArrayList<Integer> indexes1 = wordIndexes.get(word1);
        ArrayList<Integer> indexes2 = wordIndexes.get(word2);
        int i = 0, j = 0, min_dist = Integer.MAX_VALUE;

        while (i < indexes1.size() && j < indexes2.size()) {
            min_dist = Math.min(min_dist, Math.abs(indexes1.get(i) - indexes2.get(j)));
            if (indexes1.get(i) < indexes2.get(j)) {
                ++i;
            } else {
                ++j;
            }
        }
        return min_dist;
    }
}
```
The algorithm first initializes a hashmap during instantiation, with each unique word, in the array wordsDict, as keys, and their corresponding indexes (in wordsDict) as values.

The shortest() function accepts word1 and word2 as input arguments. The function is responsible for calculating and returning the minimum distance between the two input words in the given array wordsDict. To achieve that, it performs the following:

1. Store the index arrays for word1 and word2 in variables `indexes1` and `indexes2`.
2. Initialize variables `i` and `j` to 0, to iterate through the index arrays and initialize `min_dist` to the maximum value possible for the programming language.
3. Perform a while loop with the condition that `i` and `j` are lesser than the length of the arrays `indexes1` and `indexes2`, respectively.
4. Calculate `abs(indexes1[i] - indexes2[j])` and compare it against the current `min_dist`. If smaller, set `min_dist` to the new minimum distance.
5. If `indexes1[i]` is lesser than `indexes2[j]`, then increment `i`, otherwise increment `j`.
6. When the loop terminates, return `min_dist` which holds the shortest distance between the two input words in the array.

## A solution in C++

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

class WordDistance {
public:
    WordDistance(std::vector<std::string>& wordsDict) {
        for(int i = 0; i < wordsDict.size(); ++i) {
            wordIndexes[wordsDict[i]].push_back(i);
        }
    }

    int shortest(std::string word1, std::string word2) {
        std::vector<int> indexes1 = wordIndexes[word1];
        std::vector<int> indexes2 = wordIndexes[word2];
        int i = 0, j = 0, min_dist = INT_MAX;

        while(i < indexes1.size() && j < indexes2.size()) {
            min_dist = std::min(min_dist, abs(indexes1[i] - indexes2[j]));
            if(indexes1[i] < indexes2[j]) {
                ++i;
            }
            else {
                ++j;
            }
        }
        return min_dist;
    }

private:
    std::unordered_map<std::string, std::vector<int>> wordIndexes;
};
```
The algorithm first initializes a hashmap during instantiation, with each unique word, in the array wordsDict, as keys, and their corresponding indexes (in wordsDict) as values.

The shortest() function accepts word1 and word2 as input arguments. The function is responsible for calculating and returning the minimum distance between the two input words in the given array wordsDict. To achieve that, it performs the following:

1. Store the index arrays for word1 and word2 in variables `indexes1` and `indexes2`.
2. Initialize variables `i` and `j` to 0, to iterate through the index arrays and initialize `min_dist` to the maximum value possible for the programming language.
3. Perform a while loop with the condition that `i` and `j` are lesser than the length of the arrays `indexes1` and `indexes2`, respectively.
4. Calculate `abs(indexes1[i] - indexes2[j])` and compare it against the current `min_dist`. If smaller, set `min_dist` to the new minimum distance.
5. If `indexes1[i]` is lesser than `indexes2[j]`, then increment `i`, otherwise increment `j`.
6. When the loop terminates, return `min_dist` which holds the shortest distance between the two input words in the array.

## A solution in Python

```python
class WordDistance:

    def __init__(self, wordsDict):
        self.word_indexes = {}
        for i, word in enumerate(wordsDict):
            if word not in self.word_indexes:
                self.word_indexes[word] = []
            self.word_indexes[word].append(i)

    def shortest(self, word1, word2):
        indexes1 = self.word_indexes[word1]
        indexes2 = self.word_indexes[word2]
        i, j, min_dist = 0, 0, float('inf')

        while i < len(indexes1) and j < len(indexes2):
            min_dist = min(min_dist, abs(indexes1[i] - indexes2[j]))
            if indexes1[i] < indexes2[j]:
                i += 1
            else:
                j += 1

        return min_dist
```
The algorithm first initializes a hashmap during instantiation, with each unique word, in the array wordsDict, as keys, and their corresponding indexes (in wordsDict) as values.

The shortest() function accepts word1 and word2 as input arguments. The function is responsible for calculating and returning the minimum distance between the two input words in the given array wordsDict. To achieve that, it performs the following:

1. Store the index arrays for word1 and word2 in variables `indexes1` and `indexes2`.
2. Initialize variables `i` and `j` to 0, to iterate through the index arrays and initialize `min_dist` to the maximum value possible for the programming language.
3. Perform a while loop with the condition that `i` and `j` are lesser than the length of the arrays `indexes1` and `indexes2`, respectively.
4. Calculate `abs(indexes1[i] - indexes2[j])` and compare it against the current `min_dist`. If smaller, set `min_dist` to the new minimum distance.
5. If `indexes1[i]` is lesser than `indexes2[j]`, then increment `i`, otherwise increment `j`.
6. When the loop terminates, return `min_dist` which holds the shortest distance between the two input words in the array.

## A solution in Javascript

```javascript
class WordDistance {
    constructor(wordsDict) {
        this.wordIndexes = new Map();
        for (let i = 0; i < wordsDict.length; ++i) {
            if (!this.wordIndexes.has(wordsDict[i])) {
                this.wordIndexes.set(wordsDict[i], []);
            }
            this.wordIndexes.get(wordsDict[i]).push(i);
        }
    }

    shortest(word1, word2) {
        const indexes1 = this.wordIndexes.get(word1);
        const indexes2 = this.wordIndexes.get(word2);
        let i = 0, j = 0, min_dist = Number.MAX_VALUE;

        while (i < indexes1.length && j < indexes2.length) {
            min_dist = Math.min(min_dist, Math.abs(indexes1[i] - indexes2[j]));
            if (indexes1[i] < indexes2[j]) {
                ++i;
            } else {
                ++j;
            }
        }
        return min_dist;
    }
}
```
The algorithm first initializes a hashmap during instantiation, with each unique word, in the array wordsDict, as keys, and their corresponding indexes (in wordsDict) as values.

The shortest() function accepts word1 and word2 as input arguments. The function is responsible for calculating and returning the minimum distance between the two input words in the given array wordsDict. To achieve that, it performs the following:

1. Store the index arrays for word1 and word2 in variables `indexes1` and `indexes2`.
2. Initialize variables `i` and `j` to 0, to iterate through the index arrays and initialize `min_dist` to the maximum value possible for the programming language.
3. Perform a while loop with the condition that `i` and `j` are lesser than the length of the arrays `indexes1` and `indexes2`, respectively.
4. Calculate `abs(indexes1[i] - indexes2[j])` and compare it against the current `min_dist`. If smaller, set `min_dist` to the new minimum distance.
5. If `indexes1[i]` is lesser than `indexes2[j]`, then increment `i`, otherwise increment `j`.
6. When the loop terminates, return `min_dist` which holds the shortest distance between the two input words in the array.


# Shortest Word Distance III

- slug: shortest-word-distance-iii
- difficulty: Medium

Given an array of strings `wordsDict` and two strings that already exist in the array `word1` and `word2`, return _the shortest distance between the occurrence of these two words in the list_.

**Note** that `word1` and `word2` may be the same. It is guaranteed that they represent **two individual words** in the list.

**Example 1:**

**Input:** wordsDict = \["practice", "makes", "perfect", "coding", "makes"\], word1 = "makes", word2 = "coding"
**Output:** 1

**Example 2:**

**Input:** wordsDict = \["practice", "makes", "perfect", "coding", "makes"\], word1 = "makes", word2 = "makes"
**Output:** 3

**Constraints:**

*   `1 <= wordsDict.length <= 105`
*   `1 <= wordsDict[i].length <= 10`
*   `wordsDict[i]` consists of lowercase English letters.
*   `word1` and `word2` are in `wordsDict`.

## A solution in Java

```java
public int shortestDistance(String[] wordsDict, String word1, String word2) {
    int index1 = -1, index2 = -1, minDistance = Integer.MAX_VALUE;
    for (int i = 0; i < wordsDict.length; ++i) {
        if (wordsDict[i].equals(word1)) { index1 = i; }
        if (wordsDict[i].equals(word2)) { index2 = i; }
        if (index1 != -1 && index2 != -1) {
            minDistance = Math.min(minDistance, Math.abs(index1 - index2));
        }
    }
    return minDistance;
}
```
For each string in the given list `wordsDict`, initialize `index1` and `index2` to -1 and `minDistance` to the maximum possible value for the respective language. Iterate through the list of strings and update `index1` or `index2` if the current string is equal to `word1` or `word2`. If both `index1` and `index2` are not -1 (meaning both words have been found at least once), calculate the absolute difference between the indices and update `minDistance` if the current distance is less than the previous minimum distance.

Return `minDistance` once the loop is done iterating.

## A solution in C++

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

int shortestDistance(std::vector<std::string>& wordsDict, std::string word1, std::string word2) {
    int index1 = -1, index2 = -1, minDistance = std::numeric_limits<int>::max();
    for (int i = 0; i < wordsDict.size(); ++i) {
        if (wordsDict[i] == word1) { index1 = i; }
        if (wordsDict[i] == word2) { index2 = i; }
        if (index1 != -1 && index2 != -1) {
            minDistance = std::min(minDistance, std::abs(index1 - index2));
        }
    }
    return minDistance;
}
```
For each string in the given list `wordsDict`, initialize `index1` and `index2` to -1 and `minDistance` to the maximum possible value for the respective language. Iterate through the list of strings and update `index1` or `index2` if the current string is equal to `word1` or `word2`. If both `index1` and `index2` are not -1 (meaning both words have been found at least once), calculate the absolute difference between the indices and update `minDistance` if the current distance is less than the previous minimum distance.

Return `minDistance` once the loop is done iterating.

## A solution in Python

```python
def shortest_distance(words_dict, word1, word2):
    index1, index2, min_distance = -1, -1, float('inf')
    for i, word in enumerate(words_dict):
        if word == word1:
            index1 = i
        if word == word2:
            index2 = i
        if index1 != -1 and(index2 != -1):
            min_distance = min(min_distance, abs(index1 - index2))
    return min_distance
```
For each string in the given list `wordsDict`, initialize `index1` and `index2` to -1 and `minDistance` to the maximum possible value for the respective language. Iterate through the list of strings and update `index1` or `index2` if the current string is equal to `word1` or `word2`. If both `index1` and `index2` are not -1 (meaning both words have been found at least once), calculate the absolute difference between the indices and update `minDistance` if the current distance is less than the previous minimum distance.

Return `minDistance` once the loop is done iterating.

## A solution in Javascript

```javascript
function shortestDistance(wordsDict, word1, word2) {
    let index1 = -1, index2 = -1, minDistance = Infinity;
    for (let i = 0; i < wordsDict.length; ++i) {
        if (wordsDict[i] === word1) { index1 = i; }
        if (wordsDict[i] === word2) { index2 = i; }
        if (index1 !== -1 && index2 !== -1) {
            minDistance = Math.min(minDistance, Math.abs(index1 - index2));
        }
    }
    return minDistance;
}
```
For each string in the given list `wordsDict`, initialize `index1` and `index2` to -1 and `minDistance` to the maximum possible value for the respective language. Iterate through the list of strings and update `index1` or `index2` if the current string is equal to `word1` or `word2`. If both `index1` and `index2` are not -1 (meaning both words have been found at least once), calculate the absolute difference between the indices and update `minDistance` if the current distance is less than the previous minimum distance.

Return `minDistance` once the loop is done iterating.


# Strobogrammatic Number

- slug: strobogrammatic-number
- difficulty: Easy

Given a string `num` which represents an integer, return `true` _if_ `num` _is a **strobogrammatic number**_.

A **strobogrammatic number** is a number that looks the same when rotated `180` degrees (looked at upside down).

**Example 1:**

**Input:** num =  "69 "
**Output:** true

**Example 2:**

**Input:** num =  "88 "
**Output:** true

**Example 3:**

**Input:** num =  "962 "
**Output:** false

**Constraints:**

*   `1 <= num.length <= 50`
*   `num` consists of only digits.
*   `num` does not contain any leading zeros except for zero itself.

## A solution in Java

```java
public boolean isStrobogrammatic(String num) {
    HashMap<Character, Character> lookup = new HashMap<Character, Character>() {{
        put('0', '0');
        put('1', '1');
        put('6', '9');
        put('8', '8');
        put('9', '6');
    }};
    int left = 0, right = num.length() - 1;
    while(left <= right) {
        if(!lookup.containsKey(num.charAt(left)) || lookup.get(num.charAt(left)) != num.charAt(right)) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}
```
The algorithm uses a while loop and a dictionary (lookup) to check if the given string is strobogrammatic. The main idea is to iterate through the string with two pointers, `left` and `right`. The `left` pointer starts at the beginning of the string and `right` starts at the end.

For each step of the while loop:
1. Check if the character at the `left` pointer is in the `lookup` dictionary, if not, return false.
2. Check if the mapped (rotated) character of the character at the `left` pointer matches the character at the `right` pointer, if not, return false.
3. Increment `left` pointer and decrement `right` pointer.

If the loop finishes iterating through the string without returning false, then return true as the string is strobogrammatic.

## A solution in C++

```cpp
bool isStrobogrammatic(string num) {
    unordered_map<char, char> lookup {{'0', '0'}, {'1', '1'}, {'6', '9'}, {'8', '8'}, {'9', '6'}};
    int left = 0, right = num.size() - 1;
    while(left <= right) {
        if(lookup[num[left]] != num[right]) return false;
        left++;
        right--;
    }
    return true;
}
```
The algorithm uses a while loop and a dictionary (lookup) to check if the given string is strobogrammatic. The main idea is to iterate through the string with two pointers, `left` and `right`. The `left` pointer starts at the beginning of the string and `right` starts at the end.

For each step of the while loop:
1. Check if the character at the `left` pointer is in the `lookup` dictionary, if not, return false.
2. Check if the mapped (rotated) character of the character at the `left` pointer matches the character at the `right` pointer, if not, return false.
3. Increment `left` pointer and decrement `right` pointer.

If the loop finishes iterating through the string without returning false, then return true as the string is strobogrammatic.

## A solution in Python

```python
def isStrobogrammatic(num: str) -> bool:
    lookup = {'0': '0', '1': '1', '6': '9', '8': '8', '9': '6'}
    left, right = 0, len(num) - 1
    while left <= right:
        if num[left] not in lookup or lookup[num[left]] != num[right]:
            return False
        left += 1
        right -= 1
    return True
```
The algorithm uses a while loop and a dictionary (lookup) to check if the given string is strobogrammatic. The main idea is to iterate through the string with two pointers, `left` and `right`. The `left` pointer starts at the beginning of the string and `right` starts at the end.

For each step of the while loop:
1. Check if the character at the `left` pointer is in the `lookup` dictionary, if not, return false.
2. Check if the mapped (rotated) character of the character at the `left` pointer matches the character at the `right` pointer, if not, return false.
3. Increment `left` pointer and decrement `right` pointer.

If the loop finishes iterating through the string without returning false, then return true as the string is strobogrammatic.

## A solution in Javascript

```javascript
function isStrobogrammatic(num) {
    const lookup = {'0': '0', '1': '1', '6': '9', '8': '8', '9': '6'};
    let left = 0, right = num.length - 1;
    while(left <= right) {
        if(!(num[left] in lookup) || lookup[num[left]] !== num[right]) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}
```
The algorithm uses a while loop and a dictionary (lookup) to check if the given string is strobogrammatic. The main idea is to iterate through the string with two pointers, `left` and `right`. The `left` pointer starts at the beginning of the string and `right` starts at the end.

For each step of the while loop:
1. Check if the character at the `left` pointer is in the `lookup` dictionary, if not, return false.
2. Check if the mapped (rotated) character of the character at the `left` pointer matches the character at the `right` pointer, if not, return false.
3. Increment `left` pointer and decrement `right` pointer.

If the loop finishes iterating through the string without returning false, then return true as the string is strobogrammatic.


# Strobogrammatic Number II

- slug: strobogrammatic-number-ii
- difficulty: Medium

Given an integer `n`, return all the **strobogrammatic numbers** that are of length `n`. You may return the answer in **any order**.

A **strobogrammatic number** is a number that looks the same when rotated `180` degrees (looked at upside down).

**Example 1:**

**Input:** n = 2
**Output:** \["11","69","88","96"\]

**Example 2:**

**Input:** n = 1
**Output:** \["0","1","8"\]

**Constraints:**

*   `1 <= n <= 14`

## A solution in Java

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

public List<String> findStrobogrammatic(int n) {
    return helper(n, n);
}

private List<String> helper(int n, int m) {
    if (n == 0) return new ArrayList<>(Arrays.asList(""));
    if (n == 1) return new ArrayList<>(Arrays.asList("0", "1", "8"));

    List<String> list = helper(n - 2, m);
    List<String> res = new ArrayList<>();

    for (int i = 0; i < list.size(); i++) {
        String s = list.get(i);

        if (n != m) res.add("0" + s + "0");

        res.add("1" + s + "1");
        res.add("6" + s + "9");
        res.add("8" + s + "8");
        res.add("9" + s + "6");
    }

    return res;
}
```
The algorithm uses a recursive approach to find all the strobogrammatic numbers of length n. It starts by checking the base cases when n is 0 or 1, and then recursively calls the helper function with n-2. This helps to build the strobogrammatic numbers by appending to the center of the existing numbers until the desired length is reached. Inside the loop, the code adds the possible pairs of strobogrammatic digits ("1" + s + "1", "6" + s + "9", "8" + s + "8", "9" + s + "6") and for even lengths only, it adds 0s as well ("0" + s + "0"). This is because when we are building the number from the center, we cannot have leading zeros. Finally, it returns the list of strobogrammatic numbers of length n.

## A solution in C++

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

std::vector<std::string> findStrobogrammatic(int n) {
    return helper(n, n);
}

std::vector<std::string> helper(int n, int m) {
    if (n == 0) return {""};
    if (n == 1) return {"0", "1", "8"};

    std::vector<std::string> list = helper(n - 2, m);
    std::vector<std::string> res;

    for (int i = 0; i < list.size(); i++) {
        std::string s = list[i];

        if (n != m) res.push_back("0" + s + "0");

        res.push_back("1" + s + "1");
        res.push_back("6" + s + "9");
        res.push_back("8" + s + "8");
        res.push_back("9" + s + "6");
    }

    return res;
}
```
The algorithm uses a recursive approach to find all the strobogrammatic numbers of length n. It starts by checking the base cases when n is 0 or 1, and then recursively calls the helper function with n-2. This helps to build the strobogrammatic numbers by appending to the center of the existing numbers until the desired length is reached. Inside the loop, the code adds the possible pairs of strobogrammatic digits ("1" + s + "1", "6" + s + "9", "8" + s + "8", "9" + s + "6") and for even lengths only, it adds 0s as well ("0" + s + "0"). This is because when we are building the number from the center, we cannot have leading zeros. Finally, it returns the list of strobogrammatic numbers of length n.

## A solution in Python

```python
def findStrobogrammatic(n):
    def helper(n, m):
        if n == 0:
            return [""]
        if n == 1:
            return ["0", "1", "8"]

        list = helper(n - 2, m)
        res = []

        for s in list:
            if n != m:
                res.append("0" + s + "0")

            res.append("1" + s + "1")
            res.append("6" + s + "9")
            res.append("8" + s + "8")
            res.append("9" + s + "6")

        return res

    return helper(n, n)
```
The algorithm uses a recursive approach to find all the strobogrammatic numbers of length n. It starts by checking the base cases when n is 0 or 1, and then recursively calls the helper function with n-2. This helps to build the strobogrammatic numbers by appending to the center of the existing numbers until the desired length is reached. Inside the loop, the code adds the possible pairs of strobogrammatic digits ("1" + s + "1", "6" + s + "9", "8" + s + "8", "9" + s + "6") and for even lengths only, it adds 0s as well ("0" + s + "0"). This is because when we are building the number from the center, we cannot have leading zeros. Finally, it returns the list of strobogrammatic numbers of length n.

## A solution in Javascript

```javascript
function findStrobogrammatic(n) {
    return helper(n, n);
}

function helper(n, m) {
    if (n === 0) return [""];
    if (n === 1) return ["0", "1", "8"];

    const list = helper(n - 2, m);
    const res = [];

    for (let i = 0; i < list.length; i++) {
        const s = list[i];

        if (n !== m) res.push("0" + s + "0");

        res.push("1" + s + "1");
        res.push("6" + s + "9");
        res.push("8" + s + "8");
        res.push("9" + s + "6");
    }

    return res;
}
```
The algorithm uses a recursive approach to find all the strobogrammatic numbers of length n. It starts by checking the base cases when n is 0 or 1, and then recursively calls the helper function with n-2. This helps to build the strobogrammatic numbers by appending to the center of the existing numbers until the desired length is reached. Inside the loop, the code adds the possible pairs of strobogrammatic digits ("1" + s + "1", "6" + s + "9", "8" + s + "8", "9" + s + "6") and for even lengths only, it adds 0s as well ("0" + s + "0"). This is because when we are building the number from the center, we cannot have leading zeros. Finally, it returns the list of strobogrammatic numbers of length n.


# Strobogrammatic Number III

- slug: strobogrammatic-number-iii
- difficulty: Hard

Given two strings low and high that represent two integers `low` and `high` where `low <= high`, return _the number of **strobogrammatic numbers** in the range_ `[low, high]`.

A **strobogrammatic number** is a number that looks the same when rotated `180` degrees (looked at upside down).

**Example 1:**

**Input:** low = "50", high = "100"
**Output:** 3

**Example 2:**

**Input:** low = "0", high = "0"
**Output:** 1

**Constraints:**

*   `1 <= low.length, high.length <= 15`
*   `low` and `high` consist of only digits.
*   `low <= high`
*   `low` and `high` do not contain any leading zeros except for zero itself.

## A solution in Java

```java
public int strobogrammaticInRange(String low, String high) {
    int count = 0;
    for(int len = low.length(); len <= high.length(); ++len)
        count += withinRange(helper(len, len), low, high) ? 1 : 0;
    return count;
}

private String helper(int m, int n) {
    if(m == 0) return "";
    if(m == 1) return "0 1 8";
    if(n == 0) return "11 69 88 96";
    String res = "";
    for(String a : helper(m - 2, n).split(" ")) {
        if(m != n) res += a + "0" + a + " ";
        res += a + "1" + a + " ";
        res += a + "6" + a + " ";
        res += a + "8" + a + " ";
        res += a + "9" + a + " ";
    }
    return res;
}

private boolean withinRange(String num, String low, String high) {
    if(num.length() > low.length()) return num.compareTo(high) <= 0;
    if(num.length() < low.length()) return num.compareTo(low) >= 0;
    return num.compareTo(low) >= 0 && num.compareTo(high) <= 0;
}
```
To solve this problem, we will use a recursive approach.
We will create a helper function that takes two arguments m and n where m represents the remaining length of the number, and n represents the original length of the number. This helper function will return the strobogrammatic numbers of that length as a space-separated string.

In the helper function:

1. If m is 0, we return an empty string.
2. If m is 1, we return "0 1 8" representing the single-digit strobogrammatic numbers.
3. If n is 0, we return "11 69 88 96" representing the two-digit strobogrammatic numbers.

For each character `a` in the strobogrammatic numbers of length `m-2`:

1. If m is not equal to n, add a '0' in between the characters and concatenate to the result string.
2. Add '1', '6', '8', and '9' in between the characters, and concatenate to the result string.

Then, in the strobogrammaticInRange function, we iterate through the range of lengths from `low` to `high`. For each length, we check if the strobogrammatic number of that length is within the range `[low, high]`, and if it is, we increase the count by 1.

Finally, we return the total count of strobogrammatic numbers within the specified range.

## A solution in C++

```cpp
int strobogrammaticInRange(string low, string high) {
    int count = 0;
    for(int len = low.size(); len <= high.size(); ++len)
        count += helper(len, len) <= high ? helper(len, len) >= low ? 1 : 0 : 0;
    return count;
}

string helper(int m, int n) {
    if(m == 0) return "";
    if(m == 1) return "0 1 8";
    if(n == 0) return "11 69 88 96";
    string res = "";
    for(auto a : helper(m - 2, n)) {
        if(m != n) res += a + "0" + a;
        res += a + "1" + a;
        res += a + "6" + a;
        res += a + "8" + a;
        res += a + "9" + a;
    }
    return res;
}
```
To solve this problem, we will use a recursive approach.
We will create a helper function that takes two arguments m and n where m represents the remaining length of the number, and n represents the original length of the number. This helper function will return the strobogrammatic numbers of that length as a space-separated string.

In the helper function:

1. If m is 0, we return an empty string.
2. If m is 1, we return "0 1 8" representing the single-digit strobogrammatic numbers.
3. If n is 0, we return "11 69 88 96" representing the two-digit strobogrammatic numbers.

For each character `a` in the strobogrammatic numbers of length `m-2`:

1. If m is not equal to n, add a '0' in between the characters and concatenate to the result string.
2. Add '1', '6', '8', and '9' in between the characters, and concatenate to the result string.

Then, in the strobogrammaticInRange function, we iterate through the range of lengths from `low` to `high`. For each length, we check if the strobogrammatic number of that length is within the range `[low, high]`, and if it is, we increase the count by 1.

Finally, we return the total count of strobogrammatic numbers within the specified range.

## A solution in Python

```python
def strobogrammaticInRange(low, high):
    count = 0
    for len in range(len(low), len(high)+1):
        count += 1 if low <= helper(len, len) <= high else 0
    return count

def helper(m, n):
    if m == 0:
        return ""
    if m == 1:
        return "0 1 8"
    if n == 0:
        return "11 69 88 96"
    res = ""
    for a in helper(m-2, n).split():
        if m != n:
            res += a + "0" + a + " "
        res += a + "1" + a + " "
        res += a + "6" + a + " "
        res += a + "8" + a + " "
        res += a + "9" + a + " "
    return res
```
To solve this problem, we will use a recursive approach.
We will create a helper function that takes two arguments m and n where m represents the remaining length of the number, and n represents the original length of the number. This helper function will return the strobogrammatic numbers of that length as a space-separated string.

In the helper function:

1. If m is 0, we return an empty string.
2. If m is 1, we return "0 1 8" representing the single-digit strobogrammatic numbers.
3. If n is 0, we return "11 69 88 96" representing the two-digit strobogrammatic numbers.

For each character `a` in the strobogrammatic numbers of length `m-2`:

1. If m is not equal to n, add a '0' in between the characters and concatenate to the result string.
2. Add '1', '6', '8', and '9' in between the characters, and concatenate to the result string.

Then, in the strobogrammaticInRange function, we iterate through the range of lengths from `low` to `high`. For each length, we check if the strobogrammatic number of that length is within the range `[low, high]`, and if it is, we increase the count by 1.

Finally, we return the total count of strobogrammatic numbers within the specified range.

## A solution in Javascript

```javascript
function strobogrammaticInRange(low, high) {
    let count = 0;
    for (let len = low.length; len <= high.length; ++len) {
        const num = helper(len, len);
        count += (num >= low && num <= high) ? 1 : 0;
    }
    return count;
}

function helper(m, n) {
    if (m === 0) return "";
    if (m === 1) return "0 1 8";
    if (n === 0) return "11 69 88 96";
    let res = "";
    for (const a of helper(m - 2, n).split(" ")) {
        if (m !== n) res += a + "0" + a + " ";
        res += a + "1" + a + " ";
        res += a + "6" + a + " ";
        res += a + "8" + a + " ";
        res += a + "9" + a + " ";
    }
    return res;
}
```
To solve this problem, we will use a recursive approach.
We will create a helper function that takes two arguments m and n where m represents the remaining length of the number, and n represents the original length of the number. This helper function will return the strobogrammatic numbers of that length as a space-separated string.

In the helper function:

1. If m is 0, we return an empty string.
2. If m is 1, we return "0 1 8" representing the single-digit strobogrammatic numbers.
3. If n is 0, we return "11 69 88 96" representing the two-digit strobogrammatic numbers.

For each character `a` in the strobogrammatic numbers of length `m-2`:

1. If m is not equal to n, add a '0' in between the characters and concatenate to the result string.
2. Add '1', '6', '8', and '9' in between the characters, and concatenate to the result string.

Then, in the strobogrammaticInRange function, we iterate through the range of lengths from `low` to `high`. For each length, we check if the strobogrammatic number of that length is within the range `[low, high]`, and if it is, we increase the count by 1.

Finally, we return the total count of strobogrammatic numbers within the specified range.


# Group Shifted Strings

- slug: group-shifted-strings
- difficulty: Medium

We can shift a string by shifting each of its letters to its successive letter.

*   For example, `"abc "` can be shifted to be `"bcd "`.

We can keep shifting the string to form a sequence.

*   For example, we can keep shifting `"abc "` to form the sequence: `"abc " -> "bcd " -> ... -> "xyz "`.

Given an array of strings `strings`, group all `strings[i]` that belong to the same shifting sequence. You may return the answer in **any order**.

**Example 1:**

**Input:** strings = \["abc","bcd","acef","xyz","az","ba","a","z"\]
**Output:** \[\["acef"\],\["a","z"\],\["abc","bcd","xyz"\],\["az","ba"\]\]

**Example 2:**

**Input:** strings = \["a"\]
**Output:** \[\["a"\]\]

**Constraints:**

*   `1 <= strings.length <= 200`
*   `1 <= strings[i].length <= 50`
*   `strings[i]` consists of lowercase English letters.

## A solution in Java

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

public List<List<String>> groupStrings(String[] strings) {
    Map<String, List<String>> map = new HashMap<>();

    for (String s : strings) {
        StringBuilder key = new StringBuilder();
        for (char c : s.toCharArray()) {
            key.append((c - s.charAt(0) + 26) % 26).append(",");
        }
        String keyStr = key.toString();
        map.putIfAbsent(keyStr, new ArrayList<>());
        map.get(keyStr).add(s);
    }

    return new ArrayList<>(map.values());
}
```
The idea is to create a unique key for each group of strings, that depends on the relative distances between characters in a string. We iterate through the given strings and create the key for each string by taking the difference between the ASCII code of each character and that of the first character, modulo 26. We add these deltas as comma-separated elements and use them as the key in a map. Where a map is a hashmap in C++ and Java, defaultdict in Python, and Map in JavaScript. For each string, we append it to the list of strings corresponding to its group (key) in the map.

After iterating through all the strings, we return the list of groups from the map.

Note that the modulo operation and `<code>26</code>` come from the number of lowercase English letters which is 26. So, any shift greater than 25 will simply wrap around to the initial letters.

## A solution in C++

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

std::vector<std::vector<std::string>> groupStrings(std::vector<std::string>& strings) {
    std::unordered_map<std::string, std::vector<std::string>> map;

    for (const auto& s : strings) {
        std::string key;
        for (char c : s) {
            key += std::to_string((c - s[0] + 26) % 26) + ",";
        }
        map[key].push_back(s);
    }

    std::vector<std::vector<std::string>> result;
    for (auto& kv : map) {
        result.push_back(kv.second);
    }

    return result;
}
```
The idea is to create a unique key for each group of strings, that depends on the relative distances between characters in a string. We iterate through the given strings and create the key for each string by taking the difference between the ASCII code of each character and that of the first character, modulo 26. We add these deltas as comma-separated elements and use them as the key in a map. Where a map is a hashmap in C++ and Java, defaultdict in Python, and Map in JavaScript. For each string, we append it to the list of strings corresponding to its group (key) in the map.

After iterating through all the strings, we return the list of groups from the map.

Note that the modulo operation and `<code>26</code>` come from the number of lowercase English letters which is 26. So, any shift greater than 25 will simply wrap around to the initial letters.

## A solution in Python

```python
from collections import defaultdict

def groupStrings(strings):
    groups = defaultdict(list)

    for s in strings:
        key = tuple((ord(c) - ord(s[0])) % 26 for c in s)
        groups[key].append(s)

    return list(groups.values())
```
The idea is to create a unique key for each group of strings, that depends on the relative distances between characters in a string. We iterate through the given strings and create the key for each string by taking the difference between the ASCII code of each character and that of the first character, modulo 26. We add these deltas as comma-separated elements and use them as the key in a map. Where a map is a hashmap in C++ and Java, defaultdict in Python, and Map in JavaScript. For each string, we append it to the list of strings corresponding to its group (key) in the map.

After iterating through all the strings, we return the list of groups from the map.

Note that the modulo operation and `<code>26</code>` come from the number of lowercase English letters which is 26. So, any shift greater than 25 will simply wrap around to the initial letters.

## A solution in Javascript

```javascript
function groupStrings(strings) {
    const map = new Map();

    for (const s of strings) {
        let key = '';
        for (const c of s) {
            key += `${(c.charCodeAt(0) - s.charCodeAt(0) + 26) % 26},`;
        }
        if (!map.has(key)) {
            map.set(key, []);
        }
        map.get(key).push(s);
    }

    return Array.from(map.values());
}
```
The idea is to create a unique key for each group of strings, that depends on the relative distances between characters in a string. We iterate through the given strings and create the key for each string by taking the difference between the ASCII code of each character and that of the first character, modulo 26. We add these deltas as comma-separated elements and use them as the key in a map. Where a map is a hashmap in C++ and Java, defaultdict in Python, and Map in JavaScript. For each string, we append it to the list of strings corresponding to its group (key) in the map.

After iterating through all the strings, we return the list of groups from the map.

Note that the modulo operation and `<code>26</code>` come from the number of lowercase English letters which is 26. So, any shift greater than 25 will simply wrap around to the initial letters.


# Count Univalue Subtrees

- slug: count-univalue-subtrees
- difficulty: Medium

Given the `root` of a binary tree, return _the number of **uni-value**_ _subtrees_.

A **uni-value subtree** means all nodes of the subtree have the same value.

**Example 1:**

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

**Example 2:**

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

**Example 3:**

**Input:** root = \[5,5,5,5,5,null,5\]
**Output:** 6

**Constraints:**

*   The number of the node in the tree will be in the range `[0, 1000]`.
*   `-1000 <= Node.val <= 1000`

## A solution in Java

```java
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

class Solution {
    public int countUnivalSubtrees(TreeNode root) {
        return helper(root, new int[1]);
    }

    private boolean helper(TreeNode node, int[] count) {
        if (node == null) return true;

        boolean left = helper(node.left, count);
        boolean right = helper(node.right, count);

        if (left && right) {
            if (node.left != null && node.val != node.left.val) return false;
            if (node.right != null && node.val != node.right.val) return false;
            count[0]++;
            return true;
        }

        return false;
    }
}
```
The algorithm uses a recursive helper function `helper()`. This helper function takes a TreeNode and it returns a boolean value. This value indicates if the current subtree (rooted at the node) is a unival subtree or not. While doing this, it also updates the count of unival subtrees encountered.

1. If the current node is `null`, it returns `true`. This means that an empty tree is considered  a unival tree.

2. We recursively call the helper function for the left and right nodes of the current node.

3. If both left and right subtrees return `true`, it means that they are both unival subtrees. Then, we check if the current node forms a unival subtree by comparing its value with the left and right child nodes when they are not `null`. If the values are the same, we increment the count and return `true` for the current node.

4. If either of the left or right subtree is not unival, we return `false` for the current node.

Finally, we return the count of unival subtrees found during the traversal of the entire tree.

## A solution in C++

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

class Solution {
public:
    int countUnivalSubtrees(TreeNode* root) {
        int count = 0;
        helper(root, count);
        return count;
    }

    bool helper(TreeNode* node, int& count) {
        if (!node) return true;

        bool left = helper(node->left, count);
        bool right = helper(node->right, count);

        if (left && right) {
            if (node->left && node->val != node->left->val) return false;
            if (node->right && node->val != node->right->val) return false;
            count++;
            return true;
        }

        return false;
    }
};
```
The algorithm uses a recursive helper function `helper()`. This helper function takes a TreeNode and it returns a boolean value. This value indicates if the current subtree (rooted at the node) is a unival subtree or not. While doing this, it also updates the count of unival subtrees encountered.

1. If the current node is `null`, it returns `true`. This means that an empty tree is considered  a unival tree.

2. We recursively call the helper function for the left and right nodes of the current node.

3. If both left and right subtrees return `true`, it means that they are both unival subtrees. Then, we check if the current node forms a unival subtree by comparing its value with the left and right child nodes when they are not `null`. If the values are the same, we increment the count and return `true` for the current node.

4. If either of the left or right subtree is not unival, we return `false` for the current node.

Finally, we return the count of unival subtrees found during the traversal of the entire tree.

## A solution in Python

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

class Solution:
    def countUnivalSubtrees(self, root: TreeNode) -> int:
        count = 0

        def helper(node):
            nonlocal count
            if node is None:
                return True

            left = helper(node.left)
            right = helper(node.right)

            if left and right:
                if node.left and node.val != node.left.val:
                    return False
                if node.right and node.val != node.right.val:
                    return False
                count += 1
                return True

            return False

        helper(root)
        return count
```
The algorithm uses a recursive helper function `helper()`. This helper function takes a TreeNode and it returns a boolean value. This value indicates if the current subtree (rooted at the node) is a unival subtree or not. While doing this, it also updates the count of unival subtrees encountered.

1. If the current node is `null`, it returns `true`. This means that an empty tree is considered  a unival tree.

2. We recursively call the helper function for the left and right nodes of the current node.

3. If both left and right subtrees return `true`, it means that they are both unival subtrees. Then, we check if the current node forms a unival subtree by comparing its value with the left and right child nodes when they are not `null`. If the values are the same, we increment the count and return `true` for the current node.

4. If either of the left or right subtree is not unival, we return `false` for the current node.

Finally, we return the count of unival subtrees found during the traversal of the entire tree.

## A solution in Javascript

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

const countUnivalSubtrees = (root) => {
    let count = 0;

    const helper = (node) => {
        if (node === null) return true;

        const left = helper(node.left);
        const right = helper(node.right);

        if (left && right) {
            if (node.left && node.val !== node.left.val) return false;
            if (node.right && node.val !== node.right.val) return false;

            count++;
            return true;
        }

        return false;
    };

    helper(root);
    return count;
};
```
The algorithm uses a recursive helper function `helper()`. This helper function takes a TreeNode and it returns a boolean value. This value indicates if the current subtree (rooted at the node) is a unival subtree or not. While doing this, it also updates the count of unival subtrees encountered.

1. If the current node is `null`, it returns `true`. This means that an empty tree is considered  a unival tree.

2. We recursively call the helper function for the left and right nodes of the current node.

3. If both left and right subtrees return `true`, it means that they are both unival subtrees. Then, we check if the current node forms a unival subtree by comparing its value with the left and right child nodes when they are not `null`. If the values are the same, we increment the count and return `true` for the current node.

4. If either of the left or right subtree is not unival, we return `false` for the current node.

Finally, we return the count of unival subtrees found during the traversal of the entire tree.


# Flatten 2D Vector

- slug: flatten-2d-vector
- difficulty: Medium

Design an iterator to flatten a 2D vector. It should support the `next` and `hasNext` operations.

Implement the `Vector2D` class:

*   `Vector2D(int[][] vec)` initializes the object with the 2D vector `vec`.
*   `next()` returns the next element from the 2D vector and moves the pointer one step forward. You may assume that all the calls to `next` are valid.
*   `hasNext()` returns `true` if there are still some elements in the vector, and `false` otherwise.

**Example 1:**

**Input**
\[ "Vector2D ",  "next ",  "next ",  "next ",  "hasNext ",  "hasNext ",  "next ",  "hasNext "\]
\[\[\[\[1, 2\], \[3\], \[4\]\]\], \[\], \[\], \[\], \[\], \[\], \[\], \[\]\]
**Output**
\[null, 1, 2, 3, true, true, 4, false\]

**Explanation**
Vector2D vector2D = new Vector2D(\[\[1, 2\], \[3\], \[4\]\]);
vector2D.next();    // return 1
vector2D.next();    // return 2
vector2D.next();    // return 3
vector2D.hasNext(); // return True
vector2D.hasNext(); // return True
vector2D.next();    // return 4
vector2D.hasNext(); // return False

**Constraints:**

*   `0 <= vec.length <= 200`
*   `0 <= vec[i].length <= 500`
*   `-500 <= vec[i][j] <= 500`
*   At most `105` calls will be made to `next` and `hasNext`.

**Follow up:** As an added challenge, try to code it using only [iterators in C++](http://www.cplusplus.com/reference/iterator/iterator/) or [iterators in Java](http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html).

## A solution in Java

```java
import java.util.Iterator;
import java.util.List;

public class Vector2D implements Iterator<Integer> {
    private Iterator<List<Integer>> i;
    private Iterator<Integer> j;

    public Vector2D(List<List<Integer>> vec) {
        i = vec.iterator();
        if (i.hasNext()) {
            j = i.next().iterator();
        }
    }

    @Override
    public Integer next() {
        if (!hasNext()) {
            return null;
        }
        return j.next();
    }

    @Override
    public boolean hasNext() {
        if (j == null) {
            return false;
        }

        while (!j.hasNext() && i.hasNext()) {
            j = i.next().iterator();
        }

        return j.hasNext();
    }
}
```
The algorithm is quite straightforward. We track the indices `row` and `col` for traversal. In C++ and Java implementations, iterators are used for the same purpose.

1. In the constructor, we initialize the 2D vector and set the initial row and columns to zero.

2. In the `next()` function, we return the value corresponding to the indices (or iterators) and increment the column (or iterator) by 1.

3. In the `hasNext()` function, we check if we have a valid element and if not, we try to move forward to the next row (or iterator) and reset the column (or iterator) to 0. This process continues until we find a valid element, or we reach the end of the 2D vector. If a valid element is found, it returns true. Otherwise, it returns false.

## A solution in C++

```cpp
class Vector2D {
public:
    vector<vector<int>>::iterator i, i_end;
    int j = 0;

    Vector2D(vector<vector<int>>& vec) {
        i = vec.begin();
        i_end = vec.end();
    }

    int next() {
        hasNext();
        return (*i)[j++];
    }

    bool hasNext() {
        while (i != i_end && j == (*i).size()) {
            ++i;
            j = 0;
        }
        return i != i_end;
    }
};
```
The algorithm is quite straightforward. We track the indices `row` and `col` for traversal. In C++ and Java implementations, iterators are used for the same purpose.

1. In the constructor, we initialize the 2D vector and set the initial row and columns to zero.

2. In the `next()` function, we return the value corresponding to the indices (or iterators) and increment the column (or iterator) by 1.

3. In the `hasNext()` function, we check if we have a valid element and if not, we try to move forward to the next row (or iterator) and reset the column (or iterator) to 0. This process continues until we find a valid element, or we reach the end of the 2D vector. If a valid element is found, it returns true. Otherwise, it returns false.

## A solution in Python

```python
class Vector2D:
    def __init__(self, vec):
        self.vec = vec
        self.row = 0
        self.col = 0

    def next(self):
        val = self.vec[self.row][self.col]
        self.col += 1
        return val

    def hasNext(self):
        while self.row < len(self.vec):
            if self.col < len(self.vec[self.row]):
                return True
            self.row += 1
            self.col = 0
        return False
```
The algorithm is quite straightforward. We track the indices `row` and `col` for traversal. In C++ and Java implementations, iterators are used for the same purpose.

1. In the constructor, we initialize the 2D vector and set the initial row and columns to zero.

2. In the `next()` function, we return the value corresponding to the indices (or iterators) and increment the column (or iterator) by 1.

3. In the `hasNext()` function, we check if we have a valid element and if not, we try to move forward to the next row (or iterator) and reset the column (or iterator) to 0. This process continues until we find a valid element, or we reach the end of the 2D vector. If a valid element is found, it returns true. Otherwise, it returns false.

## A solution in Javascript

```javascript
class Vector2D {
    constructor(vec) {
        this.vec = vec;
        this.row = 0;
        this.col = 0;
    }

    next() {
        const val = this.vec[this.row][this.col];
        this.col++;
        return val;
    }

    hasNext() {
        while (this.row < this.vec.length) {
            if (this.col < this.vec[this.row].length) {
                return true;
            }
            this.row++;
            this.col = 0;
        }
        return false;
    }
}
```
The algorithm is quite straightforward. We track the indices `row` and `col` for traversal. In C++ and Java implementations, iterators are used for the same purpose.

1. In the constructor, we initialize the 2D vector and set the initial row and columns to zero.

2. In the `next()` function, we return the value corresponding to the indices (or iterators) and increment the column (or iterator) by 1.

3. In the `hasNext()` function, we check if we have a valid element and if not, we try to move forward to the next row (or iterator) and reset the column (or iterator) to 0. This process continues until we find a valid element, or we reach the end of the 2D vector. If a valid element is found, it returns true. Otherwise, it returns false.


# Meeting Rooms

- slug: meeting-rooms
- difficulty: Easy

Given an array of meeting time `intervals` where `intervals[i] = [starti, endi]`, determine if a person could attend all meetings.

**Example 1:**

**Input:** intervals = \[\[0,30\],\[5,10\],\[15,20\]\]
**Output:** false

**Example 2:**

**Input:** intervals = \[\[7,10\],\[2,4\]\]
**Output:** true

**Constraints:**

*   `0 <= intervals.length <= 104`
*   `intervals[i].length == 2`
*   `0 <= starti < endi <= 106`

## A solution in Java

```java
import java.util.Arrays;

public boolean canAttendMeetings(int[][] intervals) {
    Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));

    for (int i = 1; i < intervals.length; ++i) {
        if (intervals[i][0] < intervals[i - 1][1])
            return false;
    }

    return true;
}
```
1. Sort the meeting intervals by their start times.
2. Iterate through the sorted intervals.
3. Check if the start time of the current interval is less than the end time of the previous interval. If so, return false, as the person cannot attend both of these meetings.
4. If all intervals pass the check, return true, as the person can attend all meetings.

## A solution in C++

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

bool canAttendMeetings(std::vector<std::vector<int>>& intervals) {
    std::sort(intervals.begin(), intervals.end());

    for (int i = 1; i < intervals.size(); ++i) {
        if (intervals[i][0] < intervals[i - 1][1])
            return false;
    }

    return true;
}
```
1. Sort the meeting intervals by their start times.
2. Iterate through the sorted intervals.
3. Check if the start time of the current interval is less than the end time of the previous interval. If so, return false, as the person cannot attend both of these meetings.
4. If all intervals pass the check, return true, as the person can attend all meetings.

## A solution in Python

```python
def can_attend_meetings(intervals):
    intervals.sort()

    for i in range(1, len(intervals)):
        if intervals[i][0] < intervals[i - 1][1]:
            return False

    return True
```
1. Sort the meeting intervals by their start times.
2. Iterate through the sorted intervals.
3. Check if the start time of the current interval is less than the end time of the previous interval. If so, return false, as the person cannot attend both of these meetings.
4. If all intervals pass the check, return true, as the person can attend all meetings.

## A solution in Javascript

```javascript
function canAttendMeetings(intervals) {
    intervals.sort((a, b) => a[0] - b[0]);

    for (let i = 1; i < intervals.length; ++i) {
        if (intervals[i][0] < intervals[i - 1][1])
            return false;
    }

    return true;
}
```
1. Sort the meeting intervals by their start times.
2. Iterate through the sorted intervals.
3. Check if the start time of the current interval is less than the end time of the previous interval. If so, return false, as the person cannot attend both of these meetings.
4. If all intervals pass the check, return true, as the person can attend all meetings.


# Meeting Rooms II

- slug: meeting-rooms-ii
- difficulty: Medium

Given an array of meeting time intervals `intervals` where `intervals[i] = [starti, endi]`, return _the minimum number of conference rooms required_.

**Example 1:**

**Input:** intervals = \[\[0,30\],\[5,10\],\[15,20\]\]
**Output:** 2

**Example 2:**

**Input:** intervals = \[\[7,10\],\[2,4\]\]
**Output:** 1

**Constraints:**

*   `1 <= intervals.length <= 104`
*   `0 <= starti < endi <= 106`

## A solution in Java

```java
import java.util.Arrays;
import java.util.PriorityQueue;

public int minMeetingRooms(int[][] intervals) {
    if (intervals == null || intervals.length == 0) return 0;

    Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
    PriorityQueue<Integer> minHeap = new PriorityQueue<>();

    minHeap.add(intervals[0][1]);
    for (int i = 1; i < intervals.length; i++) {
        if (intervals[i][0] >= minHeap.peek()) {
            minHeap.poll();
        }
        minHeap.add(intervals[i][1]);
    }

    return minHeap.size();
}
```
1. Sort the intervals by their start times.
2. Initialize a min-heap to store the end times of the intervals.
3. Iterate through the sorted intervals.
   - If the start time of the current interval is greater than or equal to the minimum end time in the heap, it means the meeting room is available, so remove the minimum end time.
   - Add the end time of the current interval to the heap.
4. The size of the heap represents the minimum number of meeting rooms required.

## A solution in C++

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

int minMeetingRooms(std::vector<std::vector<int>>& intervals) {
    if (intervals.empty()) return 0;

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

    std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;
    min_heap.push(intervals[0][1]);

    for (int i = 1; i < intervals.size(); i++) {
        if (intervals[i][0] >= min_heap.top()) {
            min_heap.pop();
        }
        min_heap.push(intervals[i][1]);
    }

    return min_heap.size();
}
```
1. Sort the intervals by their start times.
2. Initialize a min-heap to store the end times of the intervals.
3. Iterate through the sorted intervals.
   - If the start time of the current interval is greater than or equal to the minimum end time in the heap, it means the meeting room is available, so remove the minimum end time.
   - Add the end time of the current interval to the heap.
4. The size of the heap represents the minimum number of meeting rooms required.

## A solution in Python

```python
import heapq

def minMeetingRooms(intervals):
    if not intervals:
        return 0

    intervals.sort(key=lambda x: x[0])

    min_heap = [intervals[0][1]]
    for start, end in intervals[1:]:
        if start >= min_heap[0]:
            heapq.heappop(min_heap)
        heapq.heappush(min_heap, end)

    return len(min_heap)
```
1. Sort the intervals by their start times.
2. Initialize a min-heap to store the end times of the intervals.
3. Iterate through the sorted intervals.
   - If the start time of the current interval is greater than or equal to the minimum end time in the heap, it means the meeting room is available, so remove the minimum end time.
   - Add the end time of the current interval to the heap.
4. The size of the heap represents the minimum number of meeting rooms required.

## A solution in Javascript

```javascript
function minMeetingRooms(intervals) {
    if (intervals.length === 0) return 0;

    intervals.sort((a, b) => a[0] - b[0]);
    const minHeap = [intervals[0][1]];

    for (let i = 1; i < intervals.length; i++) {
        if (intervals[i][0] >= minHeap[0]) {
            minHeap.shift();
        }
        minHeap.push(intervals[i][1]);
        minHeap.sort((a, b) => a - b);
    }

    return minHeap.length;
}
```
1. Sort the intervals by their start times.
2. Initialize a min-heap to store the end times of the intervals.
3. Iterate through the sorted intervals.
   - If the start time of the current interval is greater than or equal to the minimum end time in the heap, it means the meeting room is available, so remove the minimum end time.
   - Add the end time of the current interval to the heap.
4. The size of the heap represents the minimum number of meeting rooms required.