## LeetCode Daily Challenge 2024/10/30
#### 1671. Minimum Number of Removals to Make Mountain Array
---
### main idea : LIS/LDS
* approach : keep track of the maximum of a increasing sequence
* example : given a sequence of numbers : `[0, 1, 3, 5, 9, 15, 16, 4, 10, 11, 12, 13, 14]`
* situation : `arr = [0, 1, 3, 5, 9, 15, 16]`
* Note that :
>The index of a number x means that if a sequence ends with x, then its maximum increasing length equals the index + 1.
>For example, the maximum length of a sequence that ends with 15 is [0, 1, 3, 5, 9, 15], and the index + 1 is the length of the sequence.sequence.
* Next number = 4
* It can easily be observed that 4 and 5 are larger than [0, 1, 3]; moreover, a sequence that ends with 4 is more likely to be smaller than the next number.
* Operation: Find the upper bound of the original sequence and change it to the number 4.
### Code:
```java=
import java.util.ArrayList;
class Solution {
public int minimumMountainRemovals(int[] nums) {
ArrayList<Integer> arr_I = new ArrayList<>();
ArrayList<Integer> arr_D = new ArrayList<>();
int[] LIS = new int[nums.length];
int[] LDS = new int[nums.length];
arr_I.add(nums[0]);
LIS[0] = 1;
for (int i = 1; i < nums.length; i++) { // LIS
int target = arr_I.size();
for (int jump = arr_I.size(); jump > 0; jump /= 2) {
while (target - jump >= 0 && arr_I.get(target - jump) >= nums[i]) {
target -= jump;
}
}
LIS[i] = target + 1;
if (target == arr_I.size()) arr_I.add(nums[i]);
else arr_I.set(target, nums[i]);
}
arr_D.add(nums[nums.length - 1]);
LDS[nums.length - 1] = 1;
for (int i = nums.length - 2; i >= 0; i--) { // LDS(LIS from back)
int target = arr_D.size();
for (int jump = arr_D.size(); jump > 0; jump /= 2) {
while (target - jump >= 0 && arr_D.get(target - jump) >= nums[i]) {
target -= jump;
}
}
LDS[i] = target + 1;
if (target == arr_D.size()) arr_D.add(nums[i]);
else arr_D.set(target, nums[i]);
}
int min = Integer.MAX_VALUE;
for (int i = 1; i < nums.length - 1; i++) {
// peak cannot be the leftmost & rightmost
if (LIS[i] != 1 && LDS[i] != 1) min = Math.min(min, nums.length - (LIS[i] + LDS[i]) + 1);
}
return min;
}
}
```