You are given an integer array nums and an integer k.
Find the longest subsequence of nums that meets the following requirements:
The subsequence is strictly increasing and
The difference between adjacent elements in the subsequence is at mostk.
Return the length of the longestsubsequence that meets the requirements.
A subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.
Example 1:
Input: nums = [4,2,1,4,3,4,5,8,15], k = 3
Output: 5
Explanation:
The longest subsequence that meets the requirements is [1,3,4,5,8].
The subsequence has a length of 5, so we return 5.
Note that the subsequence [1,3,4,5,8,15] does not meet the requirements because 15 - 8 = 7 is larger than 3.
Example 2:
Input: nums = [7,4,5,1,8,12,4,7], k = 5
Output: 4
Explanation:
The longest subsequence that meets the requirements is [4,5,8,12].
The subsequence has a length of 4, so we return 4.
Example 3:
Input: nums = [1,5], k = 1
Output: 1
Explanation:
The longest subsequence that meets the requirements is [1].
The subsequence has a length of 1, so we return 1.
Constraints:
1 <= nums.length <= 105
1 <= nums[i], k <= 105
Solution: DP + Segment Tree | Max range query
Let dp[i] := length of LIS end with number i. dp[i] = 1 + max(dp[i-k:i])
Naive dp takes O(n*k) time which will cause TLE.
We can use segment tree to speed up the max range query to log(m), where m is the max value of the array.
Time complexity: O(n*logm) Space complexity: O(m)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Author: Huahua
classSolution{
public:
intlengthOfLIS(vector<int>& nums, int k) {
const int n = *max_element(begin(nums), end(nums));
Segment tree is a balanced binary tree with O(logn) height given n input segments. Segment tree supports fast range query O(logn + k), and update O(logn). Building such a tree takes O(n) time if the input is an array of numbers.