Introduction
This is an interesting question asked in the Apple OA because the condition is slightly different from the usual subarray problems.
Instead of asking whether a subarray itself satisfies some property, the task is to remove a subarray and check whether the elements left behind are strictly increasing.
The challenge is to count every possible contiguous subarray whose removal leaves a strictly increasing sequence.
With n as large as 10⁵, a direct brute-force solution becomes extremely expensive, making this a good problem for thinking about how the structure of the array can be exploited.
Problem Statement
Given an integer array arr of size n, find the number of good subarrays.
A subarray arr[l...r] is called good if, after removing all elements from index l through r, the remaining elements form a strictly increasing array.
In other words, after removing:
the elements before l and after r are joined together.
The resulting array must satisfy:
for every pair of adjacent elements.
Constraints
Example
Consider:
There are 10 good subarrays.
Some valid removals are:
For example, removing:
from:
leaves:
which is strictly increasing.
Therefore, [3,4,0] is a good subarray.
Similarly, removing:
leaves:
which is also strictly increasing.
Hence:
Key Observation
The array:
is already strictly increasing except around:
Removing a suitable contiguous section containing this problematic portion can reconnect two increasing parts.
For example:
Removing [0] gives:
Removing [4,0] gives:
Removing [3,4,0] gives:
The important condition is therefore not just whether the removed part is valid. The remaining left and right portions must also connect correctly.
Brute-Force Backtracking Approach
A straightforward way to explore the problem is to generate possible selections of indices using recursion.
The recursive function maintains:
which contains the indices currently selected for removal.
For every index, there are two choices:
- Include the index in the selected set.
- Do not include the index.
Once a selection is created, the ch2() function removes those selected positions and checks whether the remaining array is strictly increasing.
A HashSet is also used to avoid counting the same index selection more than once.
Checking a Candidate
The ch2() function performs the validation.
It first creates an array containing the elements that were not selected for removal.
For example:
Then the remaining array is scanned.
If any adjacent pair violates:
the candidate is rejected.
Otherwise, it is considered good.
Java Solution
The following is the provided recursive implementation, with comments added to make the logic easier to follow.
Dry Run
For:
Suppose the selected indices are:
Index 4 contains 0.
Removing it gives:
This is strictly increasing.
Therefore:
is counted.
Now consider:
Removing indices 2 and 3 gives:
Since:
the remaining array is not increasing.
Therefore, this candidate is rejected.
Another candidate:
removes:
and leaves:
which is strictly increasing.
So this candidate is counted.
The recursion continues until all possible selections have been explored.
Important Detail: Subarray vs Subset
There is an important distinction worth understanding when reviewing this implementation.
The problem asks for a subarray, which means the removed elements must be contiguous.
For example:
is a subarray.
But:
is not a subarray if the original array contains another element between them.
The recursive code, however, chooses individual indices independently. Therefore, it explores subsets of indices rather than explicitly restricting the selection to contiguous ranges.
This is an important conceptual difference.
For a production or interview solution, the recursion should be changed to work directly with:
so that only contiguous removals are considered.
Why This Approach Is Not Suitable for n = 10⁵
For every index, the recursion can make two choices:
This creates approximately:
possible selections.
Furthermore, each candidate is checked by constructing another array and scanning it.
Therefore, the brute-force approach grows exponentially and cannot handle:
efficiently.
This makes the problem much more interesting: the real challenge is finding the structure that allows the count to be obtained without examining every possible subarray individually.
Toward an Optimized Solution
A useful way to analyze the problem is to split the remaining array into two parts.
After removing arr[l...r], the remaining array is:
For this combined array to be strictly increasing, three things must be true:
Left part must be increasing
must already be strictly increasing.
Right part must be increasing
must already be strictly increasing.
The two parts must connect
If both parts exist:
must hold.
This observation removes the need to construct the remaining array for every candidate.
The Main Pattern
The problem can therefore be viewed as:
The only difficult part is determining whether the last element of the prefix can connect to the first element of the suffix.
This is the key observation that leads from brute force toward an efficient two-pointer/prefix-suffix based solution.
Complexity of the Provided Solution
The recursive generation can explore up to:
different index selections.
For every candidate, ch2() may also scan the entire array.
Therefore, the overall worst-case complexity is approximately:
with substantial additional memory for the recursion and stored selections.
This is only practical for very small arrays and should be considered a brute-force exploration, not a solution for the stated n = 10⁵ constraint.
Interview Takeaway
This problem teaches an important DSA lesson:
Before optimizing code, identify exactly what the problem is asking for.
There is a significant difference between:
and:
A subset can select arbitrary indices, while a subarray must be contiguous.
Once the problem is represented correctly, the next question becomes:
What must be true about the array remaining after removing [l...r]?That leads directly to the prefix/suffix observation:
This type of transformation is often much more valuable in an OA than trying to optimize an exponential recursion line by line.
Conclusion
This Apple OA-style problem combines subarray reasoning, recursion, and array properties in an interesting way.
The provided solution takes a brute-force route by recursively exploring possible index selections and checking whether the remaining elements form a strictly increasing sequence.
Although this approach is useful for understanding the problem and verifying small test cases, the constraint of 10⁵ requires a much more efficient strategy.
The major insight is to stop thinking about the removed portion itself and instead analyze the increasing prefix and increasing suffix that remain after the removal.
That shift in perspective turns an exponential search problem into one that can be approached using prefix/suffix preprocessing and two-pointer techniques.




