Problem Description
Given an integer array nums and a list of queries, implement a data structure that can efficiently answer two types of queries:
- Count the number of "peak" elements in a specified subarray. An element at index i in nums is a peak if it is strictly greater than both its previous and next elements (note that the first and last elements of any subarray cannot be peaks).
- Update the value at a specified index in nums.
For a subarray query [l, r], only indices in the range (l, r) (i.e. from l+1 to r-1) can be peaks.
Key Insights
- Precompute a helper array peaks where peaks[i] = 1 if nums[i] is a peak (and 0 otherwise) for indices 1 to n-2.
- Use a Binary Indexed Tree (BIT) / Segment Tree to support efficient range sum queries and point updates on the peaks array.
- Note that an update to nums may affect the peak status of at most three indices: index-1, index, and index+1. Recompute these affected indices after any update.
- During a subarray peak count query [l, r], exclude the boundary indices (l and r) and sum over the range [l+1, r-1] in the BIT.
Space and Time Complexity
Time Complexity:
- Preprocessing the peaks array: O(n)
- Each query (update or peak count) runs in O(log n) time due to BIT operations. Space Complexity:
- O(n) for storing the peaks array and BIT.
Solution
The solution leverages a Binary Indexed Tree (BIT) to maintain the count of peak elements dynamically while supporting updates. The steps are as follows:
- Initialize a helper array called peaks such that peaks[i] is 1 if nums[i] > nums[i-1] and nums[i] > nums[i+1], for indices from 1 to n-2; otherwise, peaks[i] is 0.
- Build a BIT over this peaks array. The BIT supports efficient point updates and range sum queries.
- For a type 1 query ([1, l, r]), compute the sum of peaks in the range from l+1 to r-1 using the BIT (if r-l is less than 2, then answer is 0).
- For a type 2 query ([2, index, val]), update the value at nums[index]. Then for each index in {index-1, index, index+1} (ensuring they are valid for peak checks), recompute the peak condition and update the BIT with the difference relative to its old state.
- Return the results for all subarray queries in order.
Code Solutions
Below are code implementations in Python, JavaScript, C++, and Java with inline comments.