# Check if There is a Valid Partition For The Array

- slug: check-if-there-is-a-valid-partition-for-the-array
- difficulty: Medium

You are given a **0-indexed** integer array `nums`. You have to partition the array into one or more **contiguous** subarrays.

We call a partition of the array **valid** if each of the obtained subarrays satisfies **one** of the following conditions:

1.  The subarray consists of **exactly** `2` equal elements. For example, the subarray `[2,2]` is good.
2.  The subarray consists of **exactly** `3` equal elements. For example, the subarray `[4,4,4]` is good.
3.  The subarray consists of **exactly** `3` consecutive increasing elements, that is, the difference between adjacent elements is `1`. For example, the subarray `[3,4,5]` is good, but the subarray `[1,3,5]` is not.

Return `true` _if the array has **at least** one valid partition_. Otherwise, return `false`.

**Example 1:**

**Input:** nums = \[4,4,4,5,6\]
**Output:** true
**Explanation:** The array can be partitioned into the subarrays \[4,4\] and \[4,5,6\].
This partition is valid, so we return true.

**Example 2:**

**Input:** nums = \[1,1,1,2\]
**Output:** false
**Explanation:** There is no valid partition for this array.

**Constraints:**

*   `2 <= nums.length <= 105`
*   `1 <= nums[i] <= 106`

## A solution in Java

```java
import java.util.HashMap;

public static boolean valid_partition(int[] nums) {
    HashMap<Integer, Integer> count = new HashMap<>();
    for (int num : nums) {
        count.put(num, count.getOrDefault(num, 0) + 1);
    }
    for (int num : count.keySet()) {
        int cnt = count.get(num);
        if (cnt == 2 || cnt == 3 || (count.containsKey(num - 1) && count.containsKey(num + 1))) {
            return true;
        }
    }
    return false;
}
```
The function first counts the frequency of each element in the given array. After that, it iterates through the counted elements map, checking whether there's a valid partition by checking the conditions: the count of the element must be exactly 2 or 3, or the element should be in the middle of a consecutive sequence (i.e., the current element minus 1 and the current element plus 1 should be present in the counted elements map as well). If at least one valid partition is found, the function returns true, otherwise false.

## A solution in C++

```cpp
bool valid_partition(vector<int>& nums) {
    unordered_map<int, int> count;
    for (int num : nums) {
        count[num]++;
    }
    for (auto& [num, cnt] : count) {
        if (cnt == 2 || cnt == 3 || (count.count(num - 1) && count.count(num + 1))) {
            return true;
        }
    }
    return false;
}
```
The function first counts the frequency of each element in the given array. After that, it iterates through the counted elements map, checking whether there's a valid partition by checking the conditions: the count of the element must be exactly 2 or 3, or the element should be in the middle of a consecutive sequence (i.e., the current element minus 1 and the current element plus 1 should be present in the counted elements map as well). If at least one valid partition is found, the function returns true, otherwise false.

## A solution in Python

```python
def valid_partition(nums):
    count = {}
    for num in nums:
        count[num] = count.get(num, 0) + 1
    for num, cnt in count.items():
        if cnt == 2 or cnt == 3 or (num - 1 in count and num + 1 in count):
            return True
    return False
```
The function first counts the frequency of each element in the given array. After that, it iterates through the counted elements map, checking whether there's a valid partition by checking the conditions: the count of the element must be exactly 2 or 3, or the element should be in the middle of a consecutive sequence (i.e., the current element minus 1 and the current element plus 1 should be present in the counted elements map as well). If at least one valid partition is found, the function returns true, otherwise false.

## A solution in Javascript

```javascript
function valid_partition(nums) {
    let count = new Map();
    for (let num of nums) {
        if (count.has(num)) {
            count.set(num, count.get(num) + 1);
        } else {
            count.set(num, 1);
        }
    }
    for (let [num, cnt] of count.entries()) {
        if (cnt === 2 || cnt === 3 || (count.has(num - 1) && count.has(num + 1))) {
            return true;
        }
    }
    return false;
}
```
The function first counts the frequency of each element in the given array. After that, it iterates through the counted elements map, checking whether there's a valid partition by checking the conditions: the count of the element must be exactly 2 or 3, or the element should be in the middle of a consecutive sequence (i.e., the current element minus 1 and the current element plus 1 should be present in the counted elements map as well). If at least one valid partition is found, the function returns true, otherwise false.


# Longest Ideal Subsequence

- slug: longest-ideal-subsequence
- difficulty: Medium

You are given a string `s` consisting of lowercase letters and an integer `k`. We call a string `t` **ideal** if the following conditions are satisfied:

*   `t` is a **subsequence** of the string `s`.
*   The absolute difference in the alphabet order of every two **adjacent** letters in `t` is less than or equal to `k`.

Return _the length of the **longest** ideal string_.

A **subsequence** is a string that can be derived from another string by deleting some or no characters without changing the order of the remaining characters.

**Note** that the alphabet order is not cyclic. For example, the absolute difference in the alphabet order of `'a'` and `'z'` is `25`, not `1`.

**Example 1:**

**Input:** s =  "acfgbd ", k = 2
**Output:** 4
**Explanation:** The longest ideal string is  "acbd ". The length of this string is 4, so 4 is returned.
Note that  "acfgbd " is not ideal because 'c' and 'f' have a difference of 3 in alphabet order.

**Example 2:**

**Input:** s =  "abcd ", k = 3
**Output:** 4
**Explanation:** The longest ideal string is  "abcd ". The length of this string is 4, so 4 is returned.

**Constraints:**

*   `1 <= s.length <= 105`
*   `0 <= k <= 25`
*   `s` consists of lowercase English letters.

## A solution in Java

```java
public int longestIdealString(String s, int k) {
    int[] dp = new int[26];

    for (char c : s.toCharArray()) {
        int current = 1;
        for (int i = 0; i < 26; ++i) {
            if (Math.abs(i - (c - 'a')) <= k)
                current = Math.max(current, dp[i] + 1);
        }
        dp[c - 'a'] = Math.max(dp[c - 'a'], current);
    }

    int max = 0;
    for (int value : dp) {
        max = Math.max(max, value);
    }

    return max;
}
```
The algorithm for this problem is dynamic programming. For each character in the input string `s`, check whether the difference of the alphabet order is within `k`. Then, update a memoization array `dp` that stores the longest ideal subsequence ending with each lowercase letter. The final solution is max of all the values in `dp`.

1. Initialize a memoization array `dp` of length 26 with all elements initially set to 0.
2. Iterate through every character `c` in the input string `s`.
3. For each character `c`, initialize a variable `current` to store the maximum length for the current character.
4. Iterate through all possible lowercase characters (from 'a' to 'z'), denoted as index `i`.
   - If the absolute difference between the index `i` and the position of character `c` in the alphabet is less than or equal to `k`, update `current` to the maximum between `current` and `dp[i] + 1`.
5. Update the value of `dp` at the position of character `c` based on `current`.
6. At the end, the longest ideal string length is the maximum value in the `dp` array. Return the max value found in `dp`.

## A solution in C++

```cpp
int longestIdealString(const string& s, int k) {
    vector<int> dp(26, 0);

    for (char c : s) {
        int current = 1;
        for (int i = 0; i < 26; ++i) {
            if (abs(i - (c - 'a')) <= k)
                current = max(current, dp[i] + 1);
        }
        dp[c - 'a'] = max(dp[c - 'a'], current);
    }

    return *max_element(dp.begin(), dp.end());
}
```
The algorithm for this problem is dynamic programming. For each character in the input string `s`, check whether the difference of the alphabet order is within `k`. Then, update a memoization array `dp` that stores the longest ideal subsequence ending with each lowercase letter. The final solution is max of all the values in `dp`.

1. Initialize a memoization array `dp` of length 26 with all elements initially set to 0.
2. Iterate through every character `c` in the input string `s`.
3. For each character `c`, initialize a variable `current` to store the maximum length for the current character.
4. Iterate through all possible lowercase characters (from 'a' to 'z'), denoted as index `i`.
   - If the absolute difference between the index `i` and the position of character `c` in the alphabet is less than or equal to `k`, update `current` to the maximum between `current` and `dp[i] + 1`.
5. Update the value of `dp` at the position of character `c` based on `current`.
6. At the end, the longest ideal string length is the maximum value in the `dp` array. Return the max value found in `dp`.

## A solution in Python

```python
def longest_ideal_string(s: str, k: int) -> int:
    dp = [0] * 26

    for c in s:
        current = 1
        for i in range(26):
            if abs(i - (ord(c) - ord('a'))) <= k:
                current = max(current, dp[i] + 1)
        dp[ord(c) - ord('a')] = max(dp[ord(c) - ord('a')], current)

    return max(dp)
```
The algorithm for this problem is dynamic programming. For each character in the input string `s`, check whether the difference of the alphabet order is within `k`. Then, update a memoization array `dp` that stores the longest ideal subsequence ending with each lowercase letter. The final solution is max of all the values in `dp`.

1. Initialize a memoization array `dp` of length 26 with all elements initially set to 0.
2. Iterate through every character `c` in the input string `s`.
3. For each character `c`, initialize a variable `current` to store the maximum length for the current character.
4. Iterate through all possible lowercase characters (from 'a' to 'z'), denoted as index `i`.
   - If the absolute difference between the index `i` and the position of character `c` in the alphabet is less than or equal to `k`, update `current` to the maximum between `current` and `dp[i] + 1`.
5. Update the value of `dp` at the position of character `c` based on `current`.
6. At the end, the longest ideal string length is the maximum value in the `dp` array. Return the max value found in `dp`.

## A solution in Javascript

```javascript
function longestIdealString(s, k) {
    let dp = new Array(26).fill(0);

    for (let c of s) {
        let current = 1;
        for (let i = 0; i < 26; ++i) {
            if (Math.abs(i - (c.charCodeAt() - 'a'.charCodeAt())) <= k)
                current = Math.max(current, dp[i] + 1);
        }
        dp[c.charCodeAt() - 'a'.charCodeAt()] = Math.max(dp[c.charCodeAt() - 'a'.charCodeAt()], current);
    }

    return Math.max(...dp);
}
```
The algorithm for this problem is dynamic programming. For each character in the input string `s`, check whether the difference of the alphabet order is within `k`. Then, update a memoization array `dp` that stores the longest ideal subsequence ending with each lowercase letter. The final solution is max of all the values in `dp`.

1. Initialize a memoization array `dp` of length 26 with all elements initially set to 0.
2. Iterate through every character `c` in the input string `s`.
3. For each character `c`, initialize a variable `current` to store the maximum length for the current character.
4. Iterate through all possible lowercase characters (from 'a' to 'z'), denoted as index `i`.
   - If the absolute difference between the index `i` and the position of character `c` in the alphabet is less than or equal to `k`, update `current` to the maximum between `current` and `dp[i] + 1`.
5. Update the value of `dp` at the position of character `c` based on `current`.
6. At the end, the longest ideal string length is the maximum value in the `dp` array. Return the max value found in `dp`.


# Minimize Maximum Value in a Grid

- slug: minimize-maximum-value-in-a-grid
- difficulty: Hard

You are given an `m x n` integer matrix `grid` containing **distinct** positive integers.

You have to replace each integer in the matrix with a positive integer satisfying the following conditions:

*   The **relative** order of every two elements that are in the same row or column should stay the **same** after the replacements.
*   The **maximum** number in the matrix after the replacements should be as **small** as possible.

The relative order stays the same if for all pairs of elements in the original matrix such that `grid[r1][c1] > grid[r2][c2]` where either `r1 == r2` or `c1 == c2`, then it must be true that `grid[r1][c1] > grid[r2][c2]` after the replacements.

For example, if `grid = [[2, 4, 5], [7, 3, 9]]` then a good replacement could be either `grid = [[1, 2, 3], [2, 1, 4]]` or `grid = [[1, 2, 3], [3, 1, 4]]`.

Return _the **resulting** matrix._ If there are multiple answers, return **any** of them.

**Example 1:**

**Input:** grid = \[\[3,1\],\[2,5\]\]
**Output:** \[\[2,1\],\[1,2\]\]
**Explanation:** The above diagram shows a valid replacement.
The maximum number in the matrix is 2. It can be shown that no smaller value can be obtained.

**Example 2:**

**Input:** grid = \[\[10\]\]
**Output:** \[\[1\]\]
**Explanation:** We replace the only number in the matrix with 1.

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `1 <= m, n <= 1000`
*   `1 <= m * n <= 105`
*   `1 <= grid[i][j] <= 109`
*   `grid` consists of distinct integers.

## A solution in Java

```java
import java.util.*;

public int[][] smallestMaxNumberGrid(int[][] grid) {
    int[] rows = new int[grid.length];
    int[] cols = new int[grid[0].length];

    for (int i = 0; i < grid.length; i++) {
        for (int j = 0; j < grid[i].length; j++) {
            rows[i] = Math.max(rows[i], grid[i][j]);
            cols[j] = Math.max(cols[j], grid[i][j]);
        }
    }

    for (int i = 0; i < grid.length; i++) {
        for (int j = 0; j < grid[i].length; j++) {
            grid[i][j] = Math.min(rows[i], cols[j]);
        }
    }

    return grid;
}
```
First, we create two arrays of length `m` and `n` to represent the rows and columns of the input grid. We then iterate through each row and column of the grid, updating the row and column arrays with the maximum values found in each. Finally, we iterate through the input grid again and update each value to be the minimum of its corresponding row and column maximum value.

## A solution in C++

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

std::vector<std::vector<int>> smallestMaxNumberGrid(std::vector<std::vector<int>>& grid) {
    std::vector<int> rows(grid.size()), cols(grid[0].size());

    for(int i = 0; i < grid.size(); i++) {
        for(int j = 0; j < grid[i].size(); j++) {
            rows[i] = std::max(rows[i], grid[i][j]);
            cols[j] = std::max(cols[j], grid[i][j]);
        }
    }

    for(int i = 0; i < grid.size(); i++) {
        for(int j = 0; j < grid[i].size(); j++) {
            grid[i][j] = std::min(rows[i], cols[j]);
        }
    }

    return grid;
}
```
First, we create two arrays of length `m` and `n` to represent the rows and columns of the input grid. We then iterate through each row and column of the grid, updating the row and column arrays with the maximum values found in each. Finally, we iterate through the input grid again and update each value to be the minimum of its corresponding row and column maximum value.

## A solution in Python

```python
def smallest_max_number_grid(grid):
    rows = [0] * len(grid)
    cols = [0] * len(grid[0])

    for i in range(len(grid)):
        for j in range(len(grid[0])):
            rows[i] = max(rows[i], grid[i][j])
            cols[j] = max(cols[j], grid[i][j])

    for i in range(len(grid)):
        for j in range(len(grid[0])):
            grid[i][j] = min(rows[i], cols[j])

    return grid
```
First, we create two arrays of length `m` and `n` to represent the rows and columns of the input grid. We then iterate through each row and column of the grid, updating the row and column arrays with the maximum values found in each. Finally, we iterate through the input grid again and update each value to be the minimum of its corresponding row and column maximum value.

## A solution in Javascript

```javascript
function smallestMaxNumberGrid(grid) {
    let rows = new Array(grid.length).fill(0);
    let cols = new Array(grid[0].length).fill(0);

    for (let i = 0; i < grid.length; i++) {
        for (let j = 0; j < grid[i].length; j++) {
            rows[i] = Math.max(rows[i], grid[i][j]);
            cols[j] = Math.max(cols[j], grid[i][j]);
        }
    }

    for (let i = 0; i < grid.length; i++) {
        for (let j = 0; j < grid[i].length; j++) {
            grid[i][j] = Math.min(rows[i], cols[j]);
        }
    }

    return grid;
}
```
First, we create two arrays of length `m` and `n` to represent the rows and columns of the input grid. We then iterate through each row and column of the grid, updating the row and column arrays with the maximum values found in each. Finally, we iterate through the input grid again and update each value to be the minimum of its corresponding row and column maximum value.


# Largest Local Values in a Matrix

- slug: largest-local-values-in-a-matrix
- difficulty: Easy

You are given an `n x n` integer matrix `grid`.

Generate an integer matrix `maxLocal` of size `(n - 2) x (n - 2)` such that:

*   `maxLocal[i][j]` is equal to the **largest** value of the `3 x 3` matrix in `grid` centered around row `i + 1` and column `j + 1`.

In other words, we want to find the largest value in every contiguous `3 x 3` matrix in `grid`.

Return _the generated matrix_.

**Example 1:**

**Input:** grid = \[\[9,9,8,1\],\[5,6,2,6\],\[8,2,6,4\],\[6,2,2,2\]\]
**Output:** \[\[9,9\],\[8,6\]\]
**Explanation:** The diagram above shows the original matrix and the generated matrix.
Notice that each value in the generated matrix corresponds to the largest value of a contiguous 3 x 3 matrix in grid.

**Example 2:**

**Input:** grid = \[\[1,1,1,1,1\],\[1,1,1,1,1\],\[1,1,2,1,1\],\[1,1,1,1,1\],\[1,1,1,1,1\]\]
**Output:** \[\[2,2,2\],\[2,2,2\],\[2,2,2\]\]
**Explanation:** Notice that the 2 is contained within every contiguous 3 x 3 matrix in grid.

**Constraints:**

*   `n == grid.length == grid[i].length`
*   `3 <= n <= 100`
*   `1 <= grid[i][j] <= 100`

## A solution in Java

```java
import java.util.ArrayList;

public ArrayList<ArrayList<Integer>> largestMatrix(int[][] grid) {
    int n = grid.length;
    ArrayList<ArrayList<Integer>> maxLocal = new ArrayList<>();

    for (int i = 1; i < n - 1; ++i) {
        maxLocal.add(new ArrayList<>());
        for (int j = 1; j < n - 1; ++j) {
            int max_val = grid[i - 1][j - 1];
            for (int x = -1; x <= 1; ++x) {
                for (int y = -1; y <= 1; ++y) {
                    max_val = Math.max(max_val, grid[i + x][j + y]);
                }
            }
            maxLocal.get(i - 1).add(max_val);
        }
    }

    return maxLocal;
}
```
The algorithm iterates through each cell of the input grid, and for each cell, it considers the 3x3 submatrix centered around that cell. It finds the maximum value in that submatrix and saves it in the corresponding position in the maxLocal matrix. To obtain the largest value from the 3x3 submatrix, nested loops iterate through all positions of the submatrix, comparing the value of each position with a variable max_val, which is then updated with the largest value found. The generated maxLocal matrix is returned as the output.

## A solution in C++

```cpp
#include <vector>

std::vector<std::vector<int>> largestMatrix(std::vector<std::vector<int>>& grid) {
    int n = grid.size();
    std::vector<std::vector<int>> maxLocal(n - 2, std::vector<int>(n - 2));

    for (int i = 1; i < n - 1; ++i) {
        for (int j = 1; j < n - 1; ++j) {
            int max_val = grid[i - 1][j - 1];
            for (int x = -1; x <= 1; ++x) {
                for (int y = -1; y <= 1; ++y) {
                    max_val = std::max(max_val, grid[i + x][j + y]);
                }
            }
            maxLocal[i - 1][j - 1] = max_val;
        }
    }

    return maxLocal;
}
```
The algorithm iterates through each cell of the input grid, and for each cell, it considers the 3x3 submatrix centered around that cell. It finds the maximum value in that submatrix and saves it in the corresponding position in the maxLocal matrix. To obtain the largest value from the 3x3 submatrix, nested loops iterate through all positions of the submatrix, comparing the value of each position with a variable max_val, which is then updated with the largest value found. The generated maxLocal matrix is returned as the output.

## A solution in Python

```python
def largest_matrix(grid):
    n = len(grid)
    maxLocal = [[0] * (n - 2) for _ in range(n - 2)]

    for i in range(1, n - 1):
        for j in range(1, n - 1):
            max_val = grid[i - 1][j - 1]
            for x in range(-1, 2):
                for y in range(-1, 2):
                    max_val = max(max_val, grid[i + x][j + y])
            maxLocal[i - 1][j - 1] = max_val

    return maxLocal
```
The algorithm iterates through each cell of the input grid, and for each cell, it considers the 3x3 submatrix centered around that cell. It finds the maximum value in that submatrix and saves it in the corresponding position in the maxLocal matrix. To obtain the largest value from the 3x3 submatrix, nested loops iterate through all positions of the submatrix, comparing the value of each position with a variable max_val, which is then updated with the largest value found. The generated maxLocal matrix is returned as the output.

## A solution in Javascript

```javascript
function largestMatrix(grid) {
    const n = grid.length;
    const maxLocal = Array.from({ length: n - 2 }, () => Array(n - 2).fill(0));

    for (let i = 1; i < n - 1; ++i) {
        for (let j = 1; j < n - 1; ++j) {
            let max_val = grid[i - 1][j - 1];
            for (let x = -1; x <= 1; ++x) {
                for (let y = -1; y <= 1; ++y) {
                    max_val = Math.max(max_val, grid[i + x][j + y]);
                }
            }
            maxLocal[i - 1][j - 1] = max_val;
        }
    }

    return maxLocal;
}
```
The algorithm iterates through each cell of the input grid, and for each cell, it considers the 3x3 submatrix centered around that cell. It finds the maximum value in that submatrix and saves it in the corresponding position in the maxLocal matrix. To obtain the largest value from the 3x3 submatrix, nested loops iterate through all positions of the submatrix, comparing the value of each position with a variable max_val, which is then updated with the largest value found. The generated maxLocal matrix is returned as the output.


# Node With Highest Edge Score

- slug: node-with-highest-edge-score
- difficulty: Medium

You are given a directed graph with `n` nodes labeled from `0` to `n - 1`, where each node has **exactly one** outgoing edge.

The graph is represented by a given **0-indexed** integer array `edges` of length `n`, where `edges[i]` indicates that there is a **directed** edge from node `i` to node `edges[i]`.

The **edge score** of a node `i` is defined as the sum of the **labels** of all the nodes that have an edge pointing to `i`.

Return _the node with the highest **edge score**_. If multiple nodes have the same **edge score**, return the node with the **smallest** index.

**Example 1:**

**Input:** edges = \[1,0,0,0,0,7,7,5\]
**Output:** 7
**Explanation:**
- The nodes 1, 2, 3 and 4 have an edge pointing to node 0. The edge score of node 0 is 1 + 2 + 3 + 4 = 10.
- The node 0 has an edge pointing to node 1. The edge score of node 1 is 0.
- The node 7 has an edge pointing to node 5. The edge score of node 5 is 7.
- The nodes 5 and 6 have an edge pointing to node 7. The edge score of node 7 is 5 + 6 = 11.
Node 7 has the highest edge score so return 7.

**Example 2:**

**Input:** edges = \[2,0,0,2\]
**Output:** 0
**Explanation:**
- The nodes 1 and 2 have an edge pointing to node 0. The edge score of node 0 is 1 + 2 = 3.
- The nodes 0 and 3 have an edge pointing to node 2. The edge score of node 2 is 0 + 3 = 3.
Nodes 0 and 2 both have an edge score of 3. Since node 0 has a smaller index, we return 0.

**Constraints:**

*   `n == edges.length`
*   `2 <= n <= 105`
*   `0 <= edges[i] < n`
*   `edges[i] != i`

## A solution in Java

```java
public int highestEdgeScoreNode(int[] edges) {
    int[] scores = new int[edges.length];

    for (int i = 0; i < edges.length; i++) {
        scores[edges[i]] += i;
    }

    int maxIndex = 0;
    for (int i = 1; i < scores.length; i++) {
        if (scores[i] > scores[maxIndex]) {
            maxIndex = i;
        }
    }

    return maxIndex;
}
```
1. Create an array "scores" with the same length as "edges" and fill it with zeros.
2. Iterate through the "edges" array. For each index i, increment the score array value at the position of edges[i] by i.
3. Find the index of the maximum value in the "scores" array and return it. In the case of a tie, the smallest index will be returned first, as required.

## A solution in C++

```cpp
int highestEdgeScoreNode(vector<int>& edges) {
    vector<int> scores(edges.size(), 0);
    for (int i = 0; i < edges.size(); ++i) {
        scores[edges[i]] += i;
    }
    return max_element(scores.begin(), scores.end()) - scores.begin();
}
```
1. Create an array "scores" with the same length as "edges" and fill it with zeros.
2. Iterate through the "edges" array. For each index i, increment the score array value at the position of edges[i] by i.
3. Find the index of the maximum value in the "scores" array and return it. In the case of a tie, the smallest index will be returned first, as required.

## A solution in Python

```python
def highest_edge_score_node(edges: List[int]) -> int:
    scores = [0] * len(edges)
    for i, edge in enumerate(edges):
        scores[edge] += i
    return scores.index(max(scores))
```
1. Create an array "scores" with the same length as "edges" and fill it with zeros.
2. Iterate through the "edges" array. For each index i, increment the score array value at the position of edges[i] by i.
3. Find the index of the maximum value in the "scores" array and return it. In the case of a tie, the smallest index will be returned first, as required.

## A solution in Javascript

```javascript
function highestEdgeScoreNode(edges) {
  const scores = new Array(edges.length).fill(0);

  for (let i = 0; i < edges.length; i++) {
    scores[edges[i]] += i;
  }

  let maxIndex = 0;
  for (let i = 1; i < scores.length; i++) {
    if (scores[i] > scores[maxIndex]) {
      maxIndex = i;
    }
  }

  return maxIndex;
}
```
1. Create an array "scores" with the same length as "edges" and fill it with zeros.
2. Iterate through the "edges" array. For each index i, increment the score array value at the position of edges[i] by i.
3. Find the index of the maximum value in the "scores" array and return it. In the case of a tie, the smallest index will be returned first, as required.


# Construct Smallest Number From DI String

- slug: construct-smallest-number-from-di-string
- difficulty: Medium

You are given a **0-indexed** string `pattern` of length `n` consisting of the characters `'I'` meaning **increasing** and `'D'` meaning **decreasing**.

A **0-indexed** string `num` of length `n + 1` is created using the following conditions:

*   `num` consists of the digits `'1'` to `'9'`, where each digit is used **at most** once.
*   If `pattern[i] == 'I'`, then `num[i] < num[i + 1]`.
*   If `pattern[i] == 'D'`, then `num[i] > num[i + 1]`.

Return _the lexicographically **smallest** possible string_ `num` _that meets the conditions._

**Example 1:**

**Input:** pattern =  "IIIDIDDD "
**Output:**  "123549876 "
**Explanation:**
At indices 0, 1, 2, and 4 we must have that num\[i\] < num\[i+1\].
At indices 3, 5, 6, and 7 we must have that num\[i\] > num\[i+1\].
Some possible values of num are  "245639871 ",  "135749862 ", and  "123849765 ".
It can be proven that  "123549876 " is the smallest possible num that meets the conditions.
Note that  "123414321 " is not possible because the digit '1' is used more than once.

**Example 2:**

**Input:** pattern =  "DDD "
**Output:**  "4321 "
**Explanation:**
Some possible values of num are  "9876 ",  "7321 ", and  "8742 ".
It can be proven that  "4321 " is the smallest possible num that meets the conditions.

**Constraints:**

*   `1 <= pattern.length <= 8`
*   `pattern` consists of only the letters `'I'` and `'D'`.

## A solution in Java

```java
public String findSmallestNum(String pattern) {
    StringBuilder num = new StringBuilder("123456789");
    for (int i = 0; i < pattern.length(); ++i) {
        if (pattern.charAt(i) == 'D') {
            int j = i;
            while (j < pattern.length() && pattern.charAt(j) == 'D') {
                ++j;
            }
            num = num.reverse().delete(0, pattern.length() - j + 1).reverse();
            num = num.reverse().append(num.substring(0, pattern.length() - i), i, j + 1);
            i = j;
        }
    }
    return num.substring(0, pattern.length() + 1);
}
```
The algorithm first initializes the `num` string to contain digits from 1 to 9. It then iterates through the `pattern` string. If it encounters a `'D'` character, it finds the stretch of consecutive `'D'` characters and reverses the corresponding stretch of numbers in `num`. If the character is `'I'`, it does nothing and moves to the next index. Finally, it returns the substring of `num` from index 0 to index `pattern.length()`, which is the result according to the provided conditions.

## A solution in C++

```cpp
#include <string>

std::string findSmallestNum(std::string pattern) {
    std::string num = "123456789";
    for (int i = 0; i < pattern.length(); ++i) {
        if (pattern[i] == 'D') {
            int j = i;
            while (j < pattern.length() && pattern[j] == 'D') {
                ++j;
            }
            std::reverse(num.begin() + i, num.begin() + j + 1);
            i = j;
        }
    }
    return num.substr(0, pattern.length() + 1);
}
```
The algorithm first initializes the `num` string to contain digits from 1 to 9. It then iterates through the `pattern` string. If it encounters a `'D'` character, it finds the stretch of consecutive `'D'` characters and reverses the corresponding stretch of numbers in `num`. If the character is `'I'`, it does nothing and moves to the next index. Finally, it returns the substring of `num` from index 0 to index `pattern.length()`, which is the result according to the provided conditions.

## A solution in Python

```python
def findSmallestNum(pattern: str) -> str:
    num = "123456789"
    i = 0
    while i < len(pattern):
        if pattern[i] == 'D':
            j = i
            while j < len(pattern) and pattern[j] == 'D':
                j += 1
            num = num[:i] + num[i:j+1][::-1] + num[j+1:]
            i = j
        else:
            i += 1
    return num[:len(pattern) + 1]
```
The algorithm first initializes the `num` string to contain digits from 1 to 9. It then iterates through the `pattern` string. If it encounters a `'D'` character, it finds the stretch of consecutive `'D'` characters and reverses the corresponding stretch of numbers in `num`. If the character is `'I'`, it does nothing and moves to the next index. Finally, it returns the substring of `num` from index 0 to index `pattern.length()`, which is the result according to the provided conditions.

## A solution in Javascript

```javascript
function findSmallestNum(pattern) {
    let num = "123456789";
    for (let i = 0; i < pattern.length; ++i) {
        if (pattern[i] === 'D') {
            let j = i;
            while (j < pattern.length && pattern[j] === 'D') {
                ++j;
            }
            num = num.substring(0, i) + num.substring(i, j + 1).split('').reverse().join('') + num.substring(j + 1);
            i = j;
        }
    }
    return num.substring(0, pattern.length + 1);
}
```
The algorithm first initializes the `num` string to contain digits from 1 to 9. It then iterates through the `pattern` string. If it encounters a `'D'` character, it finds the stretch of consecutive `'D'` characters and reverses the corresponding stretch of numbers in `num`. If the character is `'I'`, it does nothing and moves to the next index. Finally, it returns the substring of `num` from index 0 to index `pattern.length()`, which is the result according to the provided conditions.


# Count Special Integers

- slug: count-special-integers
- difficulty: Hard

We call a positive integer **special** if all of its digits are **distinct**.

Given a **positive** integer `n`, return _the number of special integers that belong to the interval_ `[1, n]`.

**Example 1:**

**Input:** n = 20
**Output:** 19
**Explanation:** All the integers from 1 to 20, except 11, are special. Thus, there are 19 special integers.

**Example 2:**

**Input:** n = 5
**Output:** 5
**Explanation:** All the integers from 1 to 5 are special.

**Example 3:**

**Input:** n = 135
**Output:** 110
**Explanation:** There are 110 integers from 1 to 135 that are special.
Some of the integers that are not special are: 22, 114, and 131.

**Constraints:**

*   `1 <= n <= 2 * 109`

## A solution in Java

```java
boolean isDistinct(int n) {
    Set<Integer> uniqueDigits = new HashSet<>();
    while (n > 0) {
        int digit = n % 10;
        if (uniqueDigits.contains(digit)) {
            return false;
        }
        uniqueDigits.add(digit);
        n /= 10;
    }
    return true;
}

int countSpecial(int n) {
    int count = 0;
    for (int i = 1; i <= n; i++) {
        if (isDistinct(i)) {
            count++;
        }
    }
    return count;
}
```
The algorithm checks all integers from 1 to n if they are special by using an auxiliary function called `isDistinct`. The `isDistinct` function checks if all digits of a given integer are distinct by using a set data structure to store the unique digits of the integer. For each digit of the given integer, if the digit is not already in the set, it's added to the set. If the digit is in the set, the function returns `false` as it is not a special integer. The main function increments the count for each integer from 1 to n that is a special integer and returns the count.

## A solution in C++

```cpp
bool isDistinct(int n) {
    std::set<int> uniqueDigits;
    while (n > 0) {
        int digit = n % 10;
        if (uniqueDigits.count(digit)) {
            return false;
        }
        uniqueDigits.insert(digit);
        n /= 10;
    }
    return true;
}

int countSpecial(int n) {
    int count = 0;
    for (int i = 1; i <= n; i++) {
        if (isDistinct(i)) {
            count++;
        }
    }
    return count;
}
```
The algorithm checks all integers from 1 to n if they are special by using an auxiliary function called `isDistinct`. The `isDistinct` function checks if all digits of a given integer are distinct by using a set data structure to store the unique digits of the integer. For each digit of the given integer, if the digit is not already in the set, it's added to the set. If the digit is in the set, the function returns `false` as it is not a special integer. The main function increments the count for each integer from 1 to n that is a special integer and returns the count.

## A solution in Python

```python
def is_distinct(n):
    unique_digits = set()
    while n > 0:
        digit = n % 10
        if digit in unique_digits:
            return False
        unique_digits.add(digit)
        n //= 10
    return True

def count_special(n):
    count = 0
    for i in range(1, n + 1):
        if is_distinct(i):
            count += 1
    return count
```
The algorithm checks all integers from 1 to n if they are special by using an auxiliary function called `isDistinct`. The `isDistinct` function checks if all digits of a given integer are distinct by using a set data structure to store the unique digits of the integer. For each digit of the given integer, if the digit is not already in the set, it's added to the set. If the digit is in the set, the function returns `false` as it is not a special integer. The main function increments the count for each integer from 1 to n that is a special integer and returns the count.

## A solution in Javascript

```javascript
function isDistinct(n) {
    const uniqueDigits = new Set();
    while (n > 0) {
        const digit = n % 10;
        if (uniqueDigits.has(digit)) {
            return false;
        }
        uniqueDigits.add(digit);
        n = Math.floor(n / 10);
    }
    return true;
}

function countSpecial(n) {
    let count = 0;
    for (let i = 1; i <= n; i++) {
        if (isDistinct(i)) {
            count++;
        }
    }
    return count;
}
```
The algorithm checks all integers from 1 to n if they are special by using an auxiliary function called `isDistinct`. The `isDistinct` function checks if all digits of a given integer are distinct by using a set data structure to store the unique digits of the integer. For each digit of the given integer, if the digit is not already in the set, it's added to the set. If the digit is in the set, the function returns `false` as it is not a special integer. The main function increments the count for each integer from 1 to n that is a special integer and returns the count.


# Choose Edges to Maximize Score in a Tree

- slug: choose-edges-to-maximize-score-in-a-tree
- difficulty: Medium

You are given a **weighted** tree consisting of `n` nodes numbered from `0` to `n - 1`.

The tree is **rooted** at node `0` and represented with a **2D** array `edges` of size `n` where `edges[i] = [pari, weighti]` indicates that node `pari` is the **parent** of node `i`, and the edge between them has a weight equal to `weighti`. Since the root does **not** have a parent, you have `edges[0] = [-1, -1]`.

Choose some edges from the tree such that no two chosen edges are **adjacent** and the **sum** of the weights of the chosen edges is maximized.

Return _the **maximum** sum of the chosen edges_.

**Note**:

*   You are allowed to **not** choose any edges in the tree, the sum of weights in this case will be `0`.
*   Two edges `Edge1` and `Edge2` in the tree are **adjacent** if they have a **common** node.
    *   In other words, they are adjacent if `Edge1` connects nodes `a` and `b` and `Edge2` connects nodes `b` and `c`.

**Example 1:**

**Input:** edges = \[\[-1,-1\],\[0,5\],\[0,10\],\[2,6\],\[2,4\]\]
**Output:** 11
**Explanation:** The above diagram shows the edges that we have to choose colored in red.
The total score is 5 + 6 = 11.
It can be shown that no better score can be obtained.

**Example 2:**

**Input:** edges = \[\[-1,-1\],\[0,5\],\[0,-6\],\[0,7\]\]
**Output:** 7
**Explanation:** We choose the edge with weight 7.
Note that we cannot choose more than one edge because all edges are adjacent to each other.

**Constraints:**

*   `n == edges.length`
*   `1 <= n <= 105`
*   `edges[i].length == 2`
*   `par0 == weight0 == -1`
*   `0 <= pari <= n - 1` for all `i >= 1`.
*   `pari != i`
*   `-106 <= weighti <= 106` for all `i >= 1`.
*   `edges` represents a valid tree.

## A solution in Java

```java
public int maxWeight(int[][] edges) {
    int n = edges.length;
    int[][] dp = new int[n][2];

    class Helper {
        void dfs(int node) {
            for (int i = 1; i < n; ++i) {
                if (edges[i][0] == node) {
                    dfs(i);
                    dp[node][0] += Math.max(dp[i][0], dp[i][1]);
                    dp[node][1] += dp[i][0];
                }
            }
            dp[node][1] += edges[node][1];
        }
    }
    Helper helper = new Helper();
    helper.dfs(0);

    return Math.max(dp[0][0], dp[0][1]);
}
```
The problem can be solved using Dynamic Programming with Tree Traversal (DFS). We use an `n x 2` DP table where `dp[i][0]` stores the maximum sum without including the weight of node i and `dp[i][1]` stores the maximum sum including the weight of node i.

We start the DFS traversal from the root. For each node i in the tree, we first perform DFS on its children. We then update the DP table for the node i:

- `dp[i][0]` is updated by adding the maximum of `dp[child][0]` and `dp[child][1]` for all its children. This is because if we don't include the edge weight of node i, we can choose to include or exclude the weights of its children to get the maximum sum.
- `dp[i][1]` is updated by adding the edge weight of node i and `dp[child][0]` for all its children. This is because if we include the edge weight of node i, we cannot include the weights of its immediate children since the chosen edges cannot be adjacent.

After the DFS traversal is completed, we return the maximum of `dp[0][0]` and `dp[0][1]` as the maximum sum of the chosen edges.

## A solution in C++

```cpp
int maxWeight(vector<vector<int>>& edges) {
    int n = edges.size();
    vector<vector<int>> dp(n, vector<int>(2));

    function<void(int)> dfs = [&](int node) {
        for (int i = 1; i < n; ++i) {
            if (edges[i][0] == node) {
                dfs(i);
                dp[node][0] += max(dp[i][0], dp[i][1]);
                dp[node][1] += dp[i][0];
            }
        }
        dp[node][1] += edges[node][1];
    };

    dfs(0);
    return max(dp[0][0], dp[0][1]);
}
```
The problem can be solved using Dynamic Programming with Tree Traversal (DFS). We use an `n x 2` DP table where `dp[i][0]` stores the maximum sum without including the weight of node i and `dp[i][1]` stores the maximum sum including the weight of node i.

We start the DFS traversal from the root. For each node i in the tree, we first perform DFS on its children. We then update the DP table for the node i:

- `dp[i][0]` is updated by adding the maximum of `dp[child][0]` and `dp[child][1]` for all its children. This is because if we don't include the edge weight of node i, we can choose to include or exclude the weights of its children to get the maximum sum.
- `dp[i][1]` is updated by adding the edge weight of node i and `dp[child][0]` for all its children. This is because if we include the edge weight of node i, we cannot include the weights of its immediate children since the chosen edges cannot be adjacent.

After the DFS traversal is completed, we return the maximum of `dp[0][0]` and `dp[0][1]` as the maximum sum of the chosen edges.

## A solution in Python

```python
def maxWeight(self, edges):
    n = len(edges)
    dp = [[0] * 2 for _ in range(n)]

    def dfs(node):
        for i in range(1, n):
            if edges[i][0] == node:
                dfs(i)
                dp[node][0] += max(dp[i][0], dp[i][1])
                dp[node][1] += dp[i][0]
        dp[node][1] += edges[node][1]

    dfs(0)
    return max(dp[0][0], dp[0][1])
```
The problem can be solved using Dynamic Programming with Tree Traversal (DFS). We use an `n x 2` DP table where `dp[i][0]` stores the maximum sum without including the weight of node i and `dp[i][1]` stores the maximum sum including the weight of node i.

We start the DFS traversal from the root. For each node i in the tree, we first perform DFS on its children. We then update the DP table for the node i:

- `dp[i][0]` is updated by adding the maximum of `dp[child][0]` and `dp[child][1]` for all its children. This is because if we don't include the edge weight of node i, we can choose to include or exclude the weights of its children to get the maximum sum.
- `dp[i][1]` is updated by adding the edge weight of node i and `dp[child][0]` for all its children. This is because if we include the edge weight of node i, we cannot include the weights of its immediate children since the chosen edges cannot be adjacent.

After the DFS traversal is completed, we return the maximum of `dp[0][0]` and `dp[0][1]` as the maximum sum of the chosen edges.

## A solution in Javascript

```javascript
function maxWeight(edges) {
    let n = edges.length;
    let dp = Array.from({ length: n }, () => [0, 0]);

    function dfs(node) {
        for (let i = 1; i < n; ++i) {
            if (edges[i][0] === node) {
                dfs(i);
                dp[node][0] += Math.max(dp[i][0], dp[i][1]);
                dp[node][1] += dp[i][0];
            }
        }
        dp[node][1] += edges[node][1];
    }

    dfs(0);
    return Math.max(dp[0][0], dp[0][1]);
}
```
The problem can be solved using Dynamic Programming with Tree Traversal (DFS). We use an `n x 2` DP table where `dp[i][0]` stores the maximum sum without including the weight of node i and `dp[i][1]` stores the maximum sum including the weight of node i.

We start the DFS traversal from the root. For each node i in the tree, we first perform DFS on its children. We then update the DP table for the node i:

- `dp[i][0]` is updated by adding the maximum of `dp[child][0]` and `dp[child][1]` for all its children. This is because if we don't include the edge weight of node i, we can choose to include or exclude the weights of its children to get the maximum sum.
- `dp[i][1]` is updated by adding the edge weight of node i and `dp[child][0]` for all its children. This is because if we include the edge weight of node i, we cannot include the weights of its immediate children since the chosen edges cannot be adjacent.

After the DFS traversal is completed, we return the maximum of `dp[0][0]` and `dp[0][1]` as the maximum sum of the chosen edges.


# Minimum Recolors to Get K Consecutive Black Blocks

- slug: minimum-recolors-to-get-k-consecutive-black-blocks
- difficulty: Easy

You are given a **0-indexed** string `blocks` of length `n`, where `blocks[i]` is either `'W'` or `'B'`, representing the color of the `ith` block. The characters `'W'` and `'B'` denote the colors white and black, respectively.

You are also given an integer `k`, which is the desired number of **consecutive** black blocks.

In one operation, you can **recolor** a white block such that it becomes a black block.

Return _the **minimum** number of operations needed such that there is at least **one** occurrence of_ `k` _consecutive black blocks._

**Example 1:**

**Input:** blocks =  "WBBWWBBWBW ", k = 7
**Output:** 3
**Explanation:**
One way to achieve 7 consecutive black blocks is to recolor the 0th, 3rd, and 4th blocks
so that blocks =  "BBBBBBBWBW ".
It can be shown that there is no way to achieve 7 consecutive black blocks in less than 3 operations.
Therefore, we return 3.

**Example 2:**

**Input:** blocks =  "WBWBBBW ", k = 2
**Output:** 0
**Explanation:**
No changes need to be made, since 2 consecutive black blocks already exist.
Therefore, we return 0.

**Constraints:**

*   `n == blocks.length`
*   `1 <= n <= 100`
*   `blocks[i]` is either `'W'` or `'B'`.
*   `1 <= k <= n`

## A solution in Java

```java
int minOperations(String blocks, int k) {
    int n = blocks.length(), res = k, w = 0, b = 0;
    for (int i = 0, j = 0; j < n; ++j) {
        if (blocks.charAt(j) == 'W') w++;
        while (b > k || (b == k && blocks.charAt(i) == 'B')) {
            if (blocks.charAt(i++) == 'W') w--;
            else b--;
        }
        if (b == k) res = Math.min(res, w);
        else b++;
    }
    return res;
}
```
The algorithm keeps a sliding window over the blocks string. It simultaneously counts the number of black blocks, `b`, and white blocks, `w`, in the sliding window.

Initially, both the left and right pointers of the sliding window, `i` and `j`, are set to 0. We iterate over the string using the right pointer, `j`. When the black count `b` equals `k`, we minimize the answer by taking the minimum of the current result and the white count `w`.

If the black count `b` is greater than `k`, or equal to `k` but the left pointer `i` points to a black block, we need to adjust the left pointer to keep only `k` black blocks in the sliding window. To do this, we increment the left pointer and decrement the corresponding color count.

Finally, we return the minimum operation count we found.

Notice that the algorithm executes in linear time. This is because each block is visited exactly twice (once by the right pointer and once by the left pointer), and the color counts are updated during the traversal. This leads to an overall time complexity of O(n) for the algorithm.

## A solution in C++

```cpp
int minOperations(string blocks, int k) {
    int n = blocks.length(), res = k, w = 0, b = 0;
    for (int i = 0, j = 0; j < n; ++j) {
        if (blocks[j] == 'W') w++;
        while (b > k || (b == k && blocks[i] == 'B')) {
            if (blocks[i++] == 'W') w--;
            else b--;
        }
        if (b == k) res = min(res, w);
        else b++;
    }
    return res;
}
```
The algorithm keeps a sliding window over the blocks string. It simultaneously counts the number of black blocks, `b`, and white blocks, `w`, in the sliding window.

Initially, both the left and right pointers of the sliding window, `i` and `j`, are set to 0. We iterate over the string using the right pointer, `j`. When the black count `b` equals `k`, we minimize the answer by taking the minimum of the current result and the white count `w`.

If the black count `b` is greater than `k`, or equal to `k` but the left pointer `i` points to a black block, we need to adjust the left pointer to keep only `k` black blocks in the sliding window. To do this, we increment the left pointer and decrement the corresponding color count.

Finally, we return the minimum operation count we found.

Notice that the algorithm executes in linear time. This is because each block is visited exactly twice (once by the right pointer and once by the left pointer), and the color counts are updated during the traversal. This leads to an overall time complexity of O(n) for the algorithm.

## A solution in Python

```python
def min_operations(blocks, k):
    n = len(blocks)
    res = k
    w = b = 0
    i = j = 0

    while j < n:
        if blocks[j] == 'W':
            w += 1
        while b > k or (b == k and blocks[i] == 'B'):
            if blocks[i] == 'W':
                w -= 1
                i += 1
            else:
                b -= 1
                i += 1
        if b == k:
            res = min(res, w)
        else:
            b += 1
        j += 1

    return res
```
The algorithm keeps a sliding window over the blocks string. It simultaneously counts the number of black blocks, `b`, and white blocks, `w`, in the sliding window.

Initially, both the left and right pointers of the sliding window, `i` and `j`, are set to 0. We iterate over the string using the right pointer, `j`. When the black count `b` equals `k`, we minimize the answer by taking the minimum of the current result and the white count `w`.

If the black count `b` is greater than `k`, or equal to `k` but the left pointer `i` points to a black block, we need to adjust the left pointer to keep only `k` black blocks in the sliding window. To do this, we increment the left pointer and decrement the corresponding color count.

Finally, we return the minimum operation count we found.

Notice that the algorithm executes in linear time. This is because each block is visited exactly twice (once by the right pointer and once by the left pointer), and the color counts are updated during the traversal. This leads to an overall time complexity of O(n) for the algorithm.

## A solution in Javascript

```javascript
function minOperations(blocks, k) {
    let n = blocks.length, res = k, w = 0, b = 0;
    for (let i = 0, j = 0; j < n; ++j) {
        if (blocks[j] === 'W') w++;
        while (b > k || (b === k && blocks[i] === 'B')) {
            if (blocks[i++] === 'W') w--;
            else b--;
        }
        if (b === k) res = Math.min(res, w);
        else b++;
    }
    return res;
}
```
The algorithm keeps a sliding window over the blocks string. It simultaneously counts the number of black blocks, `b`, and white blocks, `w`, in the sliding window.

Initially, both the left and right pointers of the sliding window, `i` and `j`, are set to 0. We iterate over the string using the right pointer, `j`. When the black count `b` equals `k`, we minimize the answer by taking the minimum of the current result and the white count `w`.

If the black count `b` is greater than `k`, or equal to `k` but the left pointer `i` points to a black block, we need to adjust the left pointer to keep only `k` black blocks in the sliding window. To do this, we increment the left pointer and decrement the corresponding color count.

Finally, we return the minimum operation count we found.

Notice that the algorithm executes in linear time. This is because each block is visited exactly twice (once by the right pointer and once by the left pointer), and the color counts are updated during the traversal. This leads to an overall time complexity of O(n) for the algorithm.


# Time Needed to Rearrange a Binary String

- slug: time-needed-to-rearrange-a-binary-string
- difficulty: Medium

You are given a binary string `s`. In one second, **all** occurrences of `"01 "` are **simultaneously** replaced with `"10 "`. This process **repeats** until no occurrences of `"01 "` exist.

Return _the number of seconds needed to complete this process._

**Example 1:**

**Input:** s =  "0110101 "
**Output:** 4
**Explanation:**
After one second, s becomes  "1011010 ".
After another second, s becomes  "1101100 ".
After the third second, s becomes  "1110100 ".
After the fourth second, s becomes  "1111000 ".
No occurrence of  "01 " exists any longer, and the process needed 4 seconds to complete,
so we return 4.

**Example 2:**

**Input:** s =  "11100 "
**Output:** 0
**Explanation:**
No occurrence of  "01 " exists in s, and the processes needed 0 seconds to complete,
so we return 0.

**Constraints:**

*   `1 <= s.length <= 1000`
*   `s[i]` is either `'0'` or `'1'`.

**Follow up:**

Can you solve this problem in O(n) time complexity?

## A solution in Java

```java
int findSecondsToTransform(String s) {
    int cnt0 = 0, cnt1 = 0;
    for (char c : s.toCharArray()) {
        if (c == '0') cnt0++;
        else cnt1++;
    }
    return Math.min(cnt0, cnt1);
}
```
The minimum number of operations needed to complete the transformation is equal to the minimum of the count of '0's and the count of '1's in the given string `s`. We loop through the string and count the number of '0's and '1's. Finally, we simply return the minimum of the counts as the result.

## A solution in C++

```cpp
int find_seconds_to_transform(const std::string &s) {
    int cnt_0 = 0, cnt_1 = 0;
    for (char c : s) {
        if (c == '0') cnt_0++;
        else cnt_1++;
    }
    return std::min(cnt_0, cnt_1);
}
```
The minimum number of operations needed to complete the transformation is equal to the minimum of the count of '0's and the count of '1's in the given string `s`. We loop through the string and count the number of '0's and '1's. Finally, we simply return the minimum of the counts as the result.

## A solution in Python

```python
def find_seconds_to_transform(s: str) -> int:
    cnt_0, cnt_1 = 0, 0
    for c in s:
        if c == '0': cnt_0 += 1
        else: cnt_1 += 1
    return min(cnt_0, cnt_1)
```
The minimum number of operations needed to complete the transformation is equal to the minimum of the count of '0's and the count of '1's in the given string `s`. We loop through the string and count the number of '0's and '1's. Finally, we simply return the minimum of the counts as the result.

## A solution in Javascript

```javascript
function findSecondsToTransform(s) {
    let cnt0 = 0, cnt1 = 0;
    for (let c of s) {
        if (c === '0') cnt0++;
        else cnt1++;
    }
    return Math.min(cnt0, cnt1);
}
```
The minimum number of operations needed to complete the transformation is equal to the minimum of the count of '0's and the count of '1's in the given string `s`. We loop through the string and count the number of '0's and '1's. Finally, we simply return the minimum of the counts as the result.


# Shifting Letters II

- slug: shifting-letters-ii
- difficulty: Medium

You are given a string `s` of lowercase English letters and a 2D integer array `shifts` where `shifts[i] = [starti, endi, directioni]`. For every `i`, **shift** the characters in `s` from the index `starti` to the index `endi` (**inclusive**) forward if `directioni = 1`, or shift the characters backward if `directioni = 0`.

Shifting a character **forward** means replacing it with the **next** letter in the alphabet (wrapping around so that `'z'` becomes `'a'`). Similarly, shifting a character **backward** means replacing it with the **previous** letter in the alphabet (wrapping around so that `'a'` becomes `'z'`).

Return _the final string after all such shifts to_ `s` _are applied_.

**Example 1:**

**Input:** s =  "abc ", shifts = \[\[0,1,0\],\[1,2,1\],\[0,2,1\]\]
**Output:**  "ace "
**Explanation:** Firstly, shift the characters from index 0 to index 1 backward. Now s =  "zac ".
Secondly, shift the characters from index 1 to index 2 forward. Now s =  "zbd ".
Finally, shift the characters from index 0 to index 2 forward. Now s =  "ace ".

**Example 2:**

**Input:** s =  "dztz ", shifts = \[\[0,0,0\],\[1,1,1\]\]
**Output:**  "catz "
**Explanation:** Firstly, shift the characters from index 0 to index 0 backward. Now s =  "cztz ".
Finally, shift the characters from index 1 to index 1 forward. Now s =  "catz ".

**Constraints:**

*   `1 <= s.length, shifts.length <= 5 * 104`
*   `shifts[i].length == 3`
*   `0 <= starti <= endi < s.length`
*   `0 <= directioni <= 1`
*   `s` consists of lowercase English letters.

## A solution in Java

```java
public String shiftCharacters(String s, int[][] shifts) {
    int[] shiftValues = new int[s.length()];
    for (int[] shift : shifts) {
        int start = shift[0], end = shift[1], direction = shift[2];
        int value = (direction == 1) ? 1 : -1;
        shiftValues[start] += value;
        if (end + 1 < s.length()) shiftValues[end + 1] -= value;
    }

    for (int i = 1; i < s.length(); i++) {
        shiftValues[i] += shiftValues[i - 1];
    }

    char[] sArray = s.toCharArray();
    for (int i = 0; i < s.length(); i++) {
        sArray[i] = (char) ((sArray[i] - 'a' + shiftValues[i]) % 26 + 'a');
    }

    return new String(sArray);
}
```
The algorithm works by first computing the total shift value for each character in the string by iterating over the shifts array. We use a separate `shiftValues` array, initialized with zeros, to store the computed shift value for each character. For each shift [start, end, direction], we increment the shift value at index 'start' by 1 or -1 depending on the direction, and decrement the shift value for the index 'end + 1' by the same amount, considering it is a valid index.

Once we have calculated the shift value increments for each character, we loop through the `shiftValues` array from the second element and add the shift value of the previous element to the current element. This way, we accumulate the shift values for each character.

Finally, we iterate through the string and update each character by applying its corresponding shift value using modular arithmetic. We add the computed shift value for each character to the distance from 'a' and take the remainder when dividing by 26, then map back to the actual character by adding the ASCII code of the letter 'a'.

Once we have iterated through the entire string, we return the updated string.

## A solution in C++

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

string shiftCharacters(string s, vector<vector<int>>& shifts) {
    vector<int> shiftValues(s.size(), 0);
    for (const auto &shift : shifts) {
        int start = shift[0], end = shift[1], direction = shift[2];
        int value = (direction == 1) ? 1 : -1;
        shiftValues[start] += value;
        if (end + 1 < s.size()) shiftValues[end + 1] -= value;
    }

    for (int i = 1; i < s.size(); i++) {
        shiftValues[i] += shiftValues[i - 1];
    }

    for (int i = 0; i < s.size(); i++) {
        s[i] = (s[i] - 'a' + shiftValues[i]) % 26 + 'a';
    }

    return s;
}
```
The algorithm works by first computing the total shift value for each character in the string by iterating over the shifts array. We use a separate `shiftValues` array, initialized with zeros, to store the computed shift value for each character. For each shift [start, end, direction], we increment the shift value at index 'start' by 1 or -1 depending on the direction, and decrement the shift value for the index 'end + 1' by the same amount, considering it is a valid index.

Once we have calculated the shift value increments for each character, we loop through the `shiftValues` array from the second element and add the shift value of the previous element to the current element. This way, we accumulate the shift values for each character.

Finally, we iterate through the string and update each character by applying its corresponding shift value using modular arithmetic. We add the computed shift value for each character to the distance from 'a' and take the remainder when dividing by 26, then map back to the actual character by adding the ASCII code of the letter 'a'.

Once we have iterated through the entire string, we return the updated string.

## A solution in Python

```python
def shiftCharacters(s: str, shifts: List[List[int]]) -> str:
    shift_values = [0] * len(s)
    for shift in shifts:
        start, end, direction = shift
        value = 1 if direction == 1 else -1
        shift_values[start] += value
        if end + 1 < len(s):
            shift_values[end + 1] -= value

    for i in range(1, len(s)):
        shift_values[i] += shift_values[i - 1]

    return ''.join(chr((ord(s[i]) - ord('a') + shift_values[i]) % 26 + ord('a')) for i in range(len(s)))
```
The algorithm works by first computing the total shift value for each character in the string by iterating over the shifts array. We use a separate `shiftValues` array, initialized with zeros, to store the computed shift value for each character. For each shift [start, end, direction], we increment the shift value at index 'start' by 1 or -1 depending on the direction, and decrement the shift value for the index 'end + 1' by the same amount, considering it is a valid index.

Once we have calculated the shift value increments for each character, we loop through the `shiftValues` array from the second element and add the shift value of the previous element to the current element. This way, we accumulate the shift values for each character.

Finally, we iterate through the string and update each character by applying its corresponding shift value using modular arithmetic. We add the computed shift value for each character to the distance from 'a' and take the remainder when dividing by 26, then map back to the actual character by adding the ASCII code of the letter 'a'.

Once we have iterated through the entire string, we return the updated string.

## A solution in Javascript

```javascript
function shiftCharacters(s, shifts) {
    const shiftValues = new Array(s.length).fill(0);
    for (const shift of shifts) {
        let [start, end, direction] = shift;
        let value = (direction === 1) ? 1 : -1;
        shiftValues[start] += value;
        if (end + 1 < s.length) shiftValues[end + 1] -= value;
    }

    for (let i = 1; i < s.length; i++) {
        shiftValues[i] += shiftValues[i - 1];
    }

    return s.split('').map((c, i) => String.fromCharCode((c.charCodeAt(0) - 'a'.charCodeAt(0) + shiftValues[i]) % 26 + 'a'.charCodeAt(0))).join('');
}
```
The algorithm works by first computing the total shift value for each character in the string by iterating over the shifts array. We use a separate `shiftValues` array, initialized with zeros, to store the computed shift value for each character. For each shift [start, end, direction], we increment the shift value at index 'start' by 1 or -1 depending on the direction, and decrement the shift value for the index 'end + 1' by the same amount, considering it is a valid index.

Once we have calculated the shift value increments for each character, we loop through the `shiftValues` array from the second element and add the shift value of the previous element to the current element. This way, we accumulate the shift values for each character.

Finally, we iterate through the string and update each character by applying its corresponding shift value using modular arithmetic. We add the computed shift value for each character to the distance from 'a' and take the remainder when dividing by 26, then map back to the actual character by adding the ASCII code of the letter 'a'.

Once we have iterated through the entire string, we return the updated string.


# Maximum Segment Sum After Removals

- slug: maximum-segment-sum-after-removals
- difficulty: Hard

You are given two **0-indexed** integer arrays `nums` and `removeQueries`, both of length `n`. For the `ith` query, the element in `nums` at the index `removeQueries[i]` is removed, splitting `nums` into different segments.

A **segment** is a contiguous sequence of **positive** integers in `nums`. A **segment sum** is the sum of every element in a segment.

Return _an integer array_ `answer`_, of length_ `n`_, where_ `answer[i]` _is the **maximum** segment sum after applying the_ `ith` _removal._

**Note:** The same index will **not** be removed more than once.

**Example 1:**

**Input:** nums = \[1,2,5,6,1\], removeQueries = \[0,3,2,4,1\]
**Output:** \[14,7,2,2,0\]
**Explanation:** Using 0 to indicate a removed element, the answer is as follows:
Query 1: Remove the 0th element, nums becomes \[0,2,5,6,1\] and the maximum segment sum is 14 for segment \[2,5,6,1\].
Query 2: Remove the 3rd element, nums becomes \[0,2,5,0,1\] and the maximum segment sum is 7 for segment \[2,5\].
Query 3: Remove the 2nd element, nums becomes \[0,2,0,0,1\] and the maximum segment sum is 2 for segment \[2\].
Query 4: Remove the 4th element, nums becomes \[0,2,0,0,0\] and the maximum segment sum is 2 for segment \[2\].
Query 5: Remove the 1st element, nums becomes \[0,0,0,0,0\] and the maximum segment sum is 0, since there are no segments.
Finally, we return \[14,7,2,2,0\].

**Example 2:**

**Input:** nums = \[3,2,11,1\], removeQueries = \[3,2,1,0\]
**Output:** \[16,5,3,0\]
**Explanation:** Using 0 to indicate a removed element, the answer is as follows:
Query 1: Remove the 3rd element, nums becomes \[3,2,11,0\] and the maximum segment sum is 16 for segment \[3,2,11\].
Query 2: Remove the 2nd element, nums becomes \[3,2,0,0\] and the maximum segment sum is 5 for segment \[3,2\].
Query 3: Remove the 1st element, nums becomes \[3,0,0,0\] and the maximum segment sum is 3 for segment \[3\].
Query 4: Remove the 0th element, nums becomes \[0,0,0,0\] and the maximum segment sum is 0, since there are no segments.
Finally, we return \[16,5,3,0\].

**Constraints:**

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

## A solution in Java

```java
import java.util.*;

public class Solution {
    public int[] maxSegSumAfterQueries(int[] nums, int[] removeQueries) {
        int n = nums.length;
        int[] answer = new int[n];
        TreeSet<Integer> removed = new TreeSet<>();
        removed.add(-1);
        removed.add(n);

        int currentSum = 0, maxSum = 0;
        for (int i = 0; i < n; ++i) {
            if (nums[i] > 0) currentSum += nums[i];
            else {
                maxSum = Math.max(maxSum, currentSum);
                currentSum = 0;
            }
        }
        maxSum = Math.max(maxSum, currentSum);

        for (int i = 0; i < n; ++i) {
            int removeIdx = removeQueries[i];
            answer[i] = maxSum;
            nums[removeIdx] = -nums[removeIdx];

            int leftIdx = removed.higher(removeIdx);
            int rightIdx = removed.lower(removeIdx);

            int leftSum = 0, rightSum = 0;
            for (int j = leftIdx - 1; j >= 0; --j) {
                if (nums[j] < 0) leftSum -= nums[j];
                else break;
            }
            for (int j = rightIdx + 1; j < n; ++j) {
                if (nums[j] < 0) rightSum -= nums[j];
                else break;
            }

            maxSum -= Math.max(0, leftSum - (-nums[removeIdx]));
            maxSum -= Math.max(0, rightSum - (-nums[removeIdx]));
            maxSum += Math.max(0, leftSum + rightSum - (-nums[removeIdx]));

            removed.add(removeIdx);
        }

        return answer;
    }
}
```
1. Create an auxiliary set `removed` to store the indices of removed elements, and initialize it with indices `-1` and `n`. These indices will be used to indicate the left and right boundaries of segments.

2. Calculate the initial maximum segment sum `maxSum` by iterating through the given `nums`.

3. Iterate through the `removeQueries` array. For each removal query:

   a. Store the current `maxSum` value in the answer array.

   b. Update the value of `nums[removeIdx]` to its negation.

   c. Determine the left and right boundaries of the segments connected to the removed element.

   d. Calculate the sums of the elements in the connected segments.

   e. Update the `maxSum` value by subtracting the segment sums connected to the removed element and adding back the sum of the modified segment after the removal.

   f. Add the index of the removed element to the `removed` set.

4. Return the answer array.

## A solution in C++

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

vector<int> maxSegSumAfterQueries(vector<int>& nums, vector<int>& removeQueries) {
    int n = nums.size();
    vector<int> answer(n);
    set<int> removed;
    removed.insert(-1);
    removed.insert(n);

    int currentSum = 0, maxSum = 0;
    for (int i = 0; i < n; ++i) {
        if (nums[i] > 0) currentSum += nums[i];
        else {
            maxSum = max(maxSum, currentSum);
            currentSum = 0;
        }
    }
    maxSum = max(maxSum, currentSum);

    for (int i = 0; i < n; ++i) {
        int removeIdx = removeQueries[i];
        answer[i] = maxSum;
        nums[removeIdx] = -nums[removeIdx];

        int leftIdx = *removed.upper_bound(removeIdx);
        int rightIdx = *prev(removed.upper_bound(removeIdx));

        int leftSum = 0, rightSum = 0;
        for (int j = leftIdx - 1; j >= 0; --j) {
            if (nums[j] < 0) leftSum -= nums[j];
            else break;
        }
        for (int j = rightIdx + 1; j < n; ++j) {
            if (nums[j] < 0) rightSum -= nums[j];
            else break;
        }

        maxSum -= max(0, leftSum - (-nums[removeIdx]));
        maxSum -= max(0, rightSum - (-nums[removeIdx]));
        maxSum += max(0, leftSum + rightSum - (-nums[removeIdx]));

        removed.insert(removeIdx);
    }

    return answer;
}
```
1. Create an auxiliary set `removed` to store the indices of removed elements, and initialize it with indices `-1` and `n`. These indices will be used to indicate the left and right boundaries of segments.

2. Calculate the initial maximum segment sum `maxSum` by iterating through the given `nums`.

3. Iterate through the `removeQueries` array. For each removal query:

   a. Store the current `maxSum` value in the answer array.

   b. Update the value of `nums[removeIdx]` to its negation.

   c. Determine the left and right boundaries of the segments connected to the removed element.

   d. Calculate the sums of the elements in the connected segments.

   e. Update the `maxSum` value by subtracting the segment sums connected to the removed element and adding back the sum of the modified segment after the removal.

   f. Add the index of the removed element to the `removed` set.

4. Return the answer array.

## A solution in Python

```python
def max_seg_sum_after_queries(nums, removeQueries):
    n = len(nums)
    answer = [0] * n
    removed = {-1, n}

    current_sum = 0
    max_sum = 0
    for x in nums:
        if x > 0:
            current_sum += x
        else:
            max_sum = max(max_sum, current_sum)
            current_sum = 0
    max_sum = max(max_sum, current_sum)

    for i, remove_idx in enumerate(removeQueries):
        answer[i] = max_sum
        nums[remove_idx] = -nums[remove_idx]

        left_idx = max(x for x in removed if x < remove_idx)
        right_idx = min(x for x in removed if x > remove_idx)

        left_sum = 0
        right_sum = 0
        for j in range(right_idx - 1, -1, -1):
            if nums[j] < 0:
                left_sum -= nums[j]
            else:
                break
        for j in range(left_idx + 1, n):
            if nums[j] < 0:
                right_sum -= nums[j]
            else:
                break

        max_sum -= max(0, left_sum - (-nums[remove_idx]))
        max_sum -= max(0, right_sum - (-nums[remove_idx]))
        max_sum += max(0, left_sum + right_sum - (-nums[remove_idx]))

        removed.add(remove_idx)

    return answer
```
1. Create an auxiliary set `removed` to store the indices of removed elements, and initialize it with indices `-1` and `n`. These indices will be used to indicate the left and right boundaries of segments.

2. Calculate the initial maximum segment sum `maxSum` by iterating through the given `nums`.

3. Iterate through the `removeQueries` array. For each removal query:

   a. Store the current `maxSum` value in the answer array.

   b. Update the value of `nums[removeIdx]` to its negation.

   c. Determine the left and right boundaries of the segments connected to the removed element.

   d. Calculate the sums of the elements in the connected segments.

   e. Update the `maxSum` value by subtracting the segment sums connected to the removed element and adding back the sum of the modified segment after the removal.

   f. Add the index of the removed element to the `removed` set.

4. Return the answer array.

## A solution in Javascript

```javascript
function maxSegSumAfterQueries(nums, removeQueries) {
    const n = nums.length;
    const answer = new Array(n);
    const removed = new Set([-1, n]);

    let currentSum = 0, maxSum = 0;
    for (const x of nums) {
        if (x > 0) currentSum += x;
        else {
            maxSum = Math.max(maxSum, currentSum);
            currentSum = 0;
        }
    }
    maxSum = Math.max(maxSum, currentSum);

    for (let i = 0; i < n; ++i) {
        const removeIdx = removeQueries[i];
        answer[i] = maxSum;
        nums[removeIdx] = -nums[removeIdx];

        const leftIdx = Math.max(...removed).filter(x => x < removeIdx);
        const rightIdx = Math.min(...removed).filter(x => x > removeIdx);

        let leftSum = 0, rightSum = 0;
        for (let j = rightIdx - 1; j >= 0; --j) {
            if (nums[j] < 0) leftSum -= nums[j];
            else break;
        }
        for (let j = leftIdx + 1; j < n; ++j) {
            if (nums[j] < 0) rightSum -= nums[j];
            else break;
        }

        maxSum -= Math.max(0, leftSum - (-nums[removeIdx]));
        maxSum -= Math.max(0, rightSum - (-nums[removeIdx]));
        maxSum += Math.max(0, leftSum + rightSum - (-nums[removeIdx]));

        removed.add(removeIdx);
    }

    return answer;
}
```
1. Create an auxiliary set `removed` to store the indices of removed elements, and initialize it with indices `-1` and `n`. These indices will be used to indicate the left and right boundaries of segments.

2. Calculate the initial maximum segment sum `maxSum` by iterating through the given `nums`.

3. Iterate through the `removeQueries` array. For each removal query:

   a. Store the current `maxSum` value in the answer array.

   b. Update the value of `nums[removeIdx]` to its negation.

   c. Determine the left and right boundaries of the segments connected to the removed element.

   d. Calculate the sums of the elements in the connected segments.

   e. Update the `maxSum` value by subtracting the segment sums connected to the removed element and adding back the sum of the modified segment after the removal.

   f. Add the index of the removed element to the `removed` set.

4. Return the answer array.


# Minimum Hours of Training to Win a Competition

- slug: minimum-hours-of-training-to-win-a-competition
- difficulty: Easy

You are entering a competition, and are given two **positive** integers `initialEnergy` and `initialExperience` denoting your initial energy and initial experience respectively.

You are also given two **0-indexed** integer arrays `energy` and `experience`, both of length `n`.

You will face `n` opponents **in order**. The energy and experience of the `ith` opponent is denoted by `energy[i]` and `experience[i]` respectively. When you face an opponent, you need to have both **strictly** greater experience and energy to defeat them and move to the next opponent if available.

Defeating the `ith` opponent **increases** your experience by `experience[i]`, but **decreases** your energy by `energy[i]`.

Before starting the competition, you can train for some number of hours. After each hour of training, you can **either** choose to increase your initial experience by one, or increase your initial energy by one.

Return _the **minimum** number of training hours required to defeat all_ `n` _opponents_.

**Example 1:**

**Input:** initialEnergy = 5, initialExperience = 3, energy = \[1,4,3,2\], experience = \[2,6,3,1\]
**Output:** 8
**Explanation:** You can increase your energy to 11 after 6 hours of training, and your experience to 5 after 2 hours of training.
You face the opponents in the following order:
- You have more energy and experience than the 0th opponent so you win.
  Your energy becomes 11 - 1 = 10, and your experience becomes 5 + 2 = 7.
- You have more energy and experience than the 1st opponent so you win.
  Your energy becomes 10 - 4 = 6, and your experience becomes 7 + 6 = 13.
- You have more energy and experience than the 2nd opponent so you win.
  Your energy becomes 6 - 3 = 3, and your experience becomes 13 + 3 = 16.
- You have more energy and experience than the 3rd opponent so you win.
  Your energy becomes 3 - 2 = 1, and your experience becomes 16 + 1 = 17.
You did a total of 6 + 2 = 8 hours of training before the competition, so we return 8.
It can be proven that no smaller answer exists.

**Example 2:**

**Input:** initialEnergy = 2, initialExperience = 4, energy = \[1\], experience = \[3\]
**Output:** 0
**Explanation:** You do not need any additional energy or experience to win the competition, so we return 0.

**Constraints:**

*   `n == energy.length == experience.length`
*   `1 <= n <= 100`
*   `1 <= initialEnergy, initialExperience, energy[i], experience[i] <= 100`

## A solution in Java

```java
import java.util.*;

class Solution {
    public int minTrainingHours(int initialEnergy, int initialExperience, int[] energy, int[] experience) {
        int n = energy.length;
        int ans = 1_000_000_000;
        for (int expGain = 0; expGain <= initialEnergy + initialExperience; ++expGain) {
            int trainingHours = expGain;
            int energyLeft = initialEnergy - expGain;
            int currExperience = initialExperience + expGain;

            for (int i = 0; i < n; ++i) {
                while (currExperience <= experience[i] || energyLeft <= energy[i]) {
                    energyLeft--;
                    trainingHours++;
                }
                energyLeft -= energy[i];
                currExperience += experience[i];
            }
            ans = Math.min(ans, trainingHours);
        }
        return ans;
    }
}
```
The main idea of the algorithm is to try all possible distributions of gained experience and energy from training hours. For each possible distribution of experience gain (i.e., each number of hours spent on gaining experience), we calculate the corresponding number of hours spent on gaining energy (since we only have two attributes to improve). Then, for each distribution, we simulate the competition and keep track of the minimum number of training hours required.

For each iteration, we simulate the competition by going through each opponent in order. When facing an opponent, if our current experience and energy level are not enough to defeat them (i.e., strictly greater than the opponent's experience and energy level), we spend more hours training on energy by decrementing the amount of energy left and incrementing the training hours.

After simulating the competition for each possible experience gain, we return the minimum training hours needed to defeat all opponents.

The time complexity of the algorithm is `O(n^2)` as we first iterate through all possible distributions with a maximum number of `n`, and then for each distribution, we iterate through all the opponents, which is also `n`. Space complexity is `O(1)` as we only use constant extra space for storing variables.

## A solution in C++

```cpp
#include <vector>

int minTrainingHours(int initialEnergy, int initialExperience, std::vector<int>& energy, std::vector<int>& experience) {
    int n = energy.size();
    int ans = 1e9;
    for (int expGain = 0; expGain <= initialEnergy + initialExperience; ++expGain) {
        int trainingHours = expGain;
        int energyLeft = initialEnergy - expGain;
        int currExperience = initialExperience + expGain;

        for (int i = 0; i < n; ++i) {
            while (currExperience <= experience[i] || energyLeft <= energy[i]) {
                energyLeft--;
                trainingHours++;
            }
            energyLeft -= energy[i];
            currExperience += experience[i];
        }
        ans = std::min(ans, trainingHours);
    }
    return ans;
}
```
The main idea of the algorithm is to try all possible distributions of gained experience and energy from training hours. For each possible distribution of experience gain (i.e., each number of hours spent on gaining experience), we calculate the corresponding number of hours spent on gaining energy (since we only have two attributes to improve). Then, for each distribution, we simulate the competition and keep track of the minimum number of training hours required.

For each iteration, we simulate the competition by going through each opponent in order. When facing an opponent, if our current experience and energy level are not enough to defeat them (i.e., strictly greater than the opponent's experience and energy level), we spend more hours training on energy by decrementing the amount of energy left and incrementing the training hours.

After simulating the competition for each possible experience gain, we return the minimum training hours needed to defeat all opponents.

The time complexity of the algorithm is `O(n^2)` as we first iterate through all possible distributions with a maximum number of `n`, and then for each distribution, we iterate through all the opponents, which is also `n`. Space complexity is `O(1)` as we only use constant extra space for storing variables.

## A solution in Python

```python
def min_training_hours(initial_energy, initial_experience, energy, experience):
    n = len(energy)
    ans = int(1e9)
    for exp_gain in range(initial_energy + initial_experience + 1):
        training_hours = exp_gain
        energy_left = initial_energy - exp_gain
        curr_experience = initial_experience + exp_gain

        for i in range(n):
            while curr_experience <= experience[i] or energy_left <= energy[i]:
                energy_left -= 1
                training_hours += 1
            energy_left -= energy[i]
            curr_experience += experience[i]
        ans = min(ans, training_hours)
    return ans
```
The main idea of the algorithm is to try all possible distributions of gained experience and energy from training hours. For each possible distribution of experience gain (i.e., each number of hours spent on gaining experience), we calculate the corresponding number of hours spent on gaining energy (since we only have two attributes to improve). Then, for each distribution, we simulate the competition and keep track of the minimum number of training hours required.

For each iteration, we simulate the competition by going through each opponent in order. When facing an opponent, if our current experience and energy level are not enough to defeat them (i.e., strictly greater than the opponent's experience and energy level), we spend more hours training on energy by decrementing the amount of energy left and incrementing the training hours.

After simulating the competition for each possible experience gain, we return the minimum training hours needed to defeat all opponents.

The time complexity of the algorithm is `O(n^2)` as we first iterate through all possible distributions with a maximum number of `n`, and then for each distribution, we iterate through all the opponents, which is also `n`. Space complexity is `O(1)` as we only use constant extra space for storing variables.

## A solution in Javascript

```javascript
function minTrainingHours(initialEnergy, initialExperience, energy, experience) {
    const n = energy.length;
    let ans = 1e9;
    for (let expGain = 0; expGain <= initialEnergy + initialExperience; ++expGain) {
        let trainingHours = expGain;
        let energyLeft = initialEnergy - expGain;
        let currExperience = initialExperience + expGain;

        for (let i = 0; i < n; ++i) {
            while (currExperience <= experience[i] || energyLeft <= energy[i]) {
                energyLeft--;
                trainingHours++;
            }
            energyLeft -= energy[i];
            currExperience += experience[i];
        }
        ans = Math.min(ans, trainingHours);
    }
    return ans;
}
```
The main idea of the algorithm is to try all possible distributions of gained experience and energy from training hours. For each possible distribution of experience gain (i.e., each number of hours spent on gaining experience), we calculate the corresponding number of hours spent on gaining energy (since we only have two attributes to improve). Then, for each distribution, we simulate the competition and keep track of the minimum number of training hours required.

For each iteration, we simulate the competition by going through each opponent in order. When facing an opponent, if our current experience and energy level are not enough to defeat them (i.e., strictly greater than the opponent's experience and energy level), we spend more hours training on energy by decrementing the amount of energy left and incrementing the training hours.

After simulating the competition for each possible experience gain, we return the minimum training hours needed to defeat all opponents.

The time complexity of the algorithm is `O(n^2)` as we first iterate through all possible distributions with a maximum number of `n`, and then for each distribution, we iterate through all the opponents, which is also `n`. Space complexity is `O(1)` as we only use constant extra space for storing variables.


# Largest Palindromic Number

- slug: largest-palindromic-number
- difficulty: Medium

You are given a string `num` consisting of digits only.

Return _the **largest palindromic** integer (in the form of a string) that can be formed using digits taken from_ `num`. It should not contain **leading zeroes**.

**Notes:**

*   You do **not** need to use all the digits of `num`, but you must use **at least** one digit.
*   The digits can be reordered.

**Example 1:**

**Input:** num =  "444947137 "
**Output:**  "7449447 "
**Explanation:**
Use the digits  "4449477 " from  "**44494****7**13**7** " to form the palindromic integer  "7449447 ".
It can be shown that  "7449447 " is the largest palindromic integer that can be formed.

**Example 2:**

**Input:** num =  "00009 "
**Output:**  "9 "
**Explanation:**
It can be shown that  "9 " is the largest palindromic integer that can be formed.
Note that the integer returned should not contain leading zeroes.

**Constraints:**

*   `1 <= num.length <= 105`
*   `num` consists of digits.

## A solution in Java

```java
public boolean rootSumEqual(TreeNode root) {
    if (root == null) return false;
    return (root.val == root.left.val + root.right.val);
}
```
The algorithm checks if the given root node exists, and if it does, it checks whether the value of the root is equal to the sum of the values of its left and right children. If the root does not exist, it returns false. This works for a tree consisting of exactly 3 nodes as specified in the question.

## A solution in C++

```cpp
bool rootSumEqual(Node* root) {
    if (!root) return false;
    return (root->val == root->left->val + root->right->val);
}
```
The algorithm checks if the given root node exists, and if it does, it checks whether the value of the root is equal to the sum of the values of its left and right children. If the root does not exist, it returns false. This works for a tree consisting of exactly 3 nodes as specified in the question.

## A solution in Python

```python
def root_sum_equal(root):
    if not root:
        return False
    return root.val == root.left.val + root.right.val
```
The algorithm checks if the given root node exists, and if it does, it checks whether the value of the root is equal to the sum of the values of its left and right children. If the root does not exist, it returns false. This works for a tree consisting of exactly 3 nodes as specified in the question.

## A solution in Javascript

```javascript
function rootSumEqual(root) {
    if (!root) return false;
    return (root.val === root.left.val + root.right.val);
}
```
The algorithm checks if the given root node exists, and if it does, it checks whether the value of the root is equal to the sum of the values of its left and right children. If the root does not exist, it returns false. This works for a tree consisting of exactly 3 nodes as specified in the question.