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 most
k
.
Return the length of the longest subsequence 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 class Solution { public: int lengthOfLIS(vector<int>& nums, int k) { const int n = *max_element(begin(nums), end(nums)); vector<int> dp(2 * (n + 1)); auto query = [&](int l, int r) -> int { int ans = 0; for (l += n, r += n; l < r; l >>= 1, r >>= 1) { if (l & 1) ans = max(ans, dp[l++]); if (r & 1) ans = max(ans, dp[--r]); } return ans; }; auto update = [&](int i, int val) -> void { dp[i += n] = val; while (i > 1) { i >>= 1; dp[i] = max(dp[i * 2], dp[i * 2 + 1]); } }; int ans = 0; for (int x : nums) { int cur = 1 + query(max(1, x - k), x); update(x, cur); ans = max(ans, cur); } return ans; } }; |