Input: nums =[4,2,1,4,3,4,5,8,15], k =3Output: 5Explanation:
The longest subsequence that meets the requirements is[1,3,4,5,8].The subsequence has a length of 5, so we return5.Note that the subsequence [1,3,4,5,8,15] does not meet the requirements because 15-8=7is larger than 3.
Input: nums =[7,4,5,1,8,12,4,7], k =5Output: 4Explanation:
The longest subsequence that meets the requirements is[4,5,8,12].The subsequence has a length of 4, so we return4.
Input: nums =[1,5], k =1Output: 1Explanation:
The longest subsequence that meets the requirements is[1].The subsequence has a length of 1, so we return1.
To efficiently find the longest increasing subsequence with adjacent difference at most k, we use a segment tree (or binary indexed tree) to keep track of the maximum dp value for all possible previous numbers in the valid range. For each number, we query the segment tree for the best previous result and update the tree with the new dp value.
classSegmentTree {
vector<int> tree;
int n;
public: SegmentTree(int size) : n(size), tree(2*size) {}
voidupdate(int i, int val) {
i += n;
tree[i] = max(tree[i], val);
for (i /=2; i >0; i /=2)
tree[i] = max(tree[2*i], tree[2*i+1]);
}
intquery(int l, int r) {
int res =0;
for (l += n, r += n; l < r; l /=2, r /=2) {
if (l%2) res = max(res, tree[l++]);
if (r%2) res = max(res, tree[--r]);
}
return res;
}
};
classSolution {
public:int lengthOfLIS(vector<int>& nums, int k) {
set<int> s(nums.begin(), nums.end());
vector<int> vals(s.begin(), s.end());
unordered_map<int, int> idx;
for (int i =0; i < vals.size(); ++i) idx[vals[i]] = i;
SegmentTree st(vals.size());
int ans =0;
for (int x : nums) {
int l = lower_bound(vals.begin(), vals.end(), x-k) - vals.begin();
int r = lower_bound(vals.begin(), vals.end(), x) - vals.begin();
int best = st.query(l, r);
int cur = best +1;
st.update(idx[x], cur);
ans = max(ans, cur);
}
return ans;
}
};
1
// Omitted for brevity. See Python for main logic.
1
// Omitted for brevity. See Python for main logic.
1
// Omitted for brevity. See Python for main logic.
classSegmentTree:
def__init__(self, size):
self.N =1while self.N < size:
self.N <<=1 self.tree = [0] * (2*self.N)
defupdate(self, i, val):
i += self.N
self.tree[i] = max(self.tree[i], val)
while i >1:
i //=2 self.tree[i] = max(self.tree[2*i], self.tree[2*i+1])
defquery(self, l, r):
res =0 l += self.N
r += self.N
while l < r:
if l %2:
res = max(res, self.tree[l])
l +=1if r %2:
r -=1 res = max(res, self.tree[r])
l //=2 r //=2return res
classSolution:
deflengthOfLIS(self, nums: list[int], k: int) -> int:
vals = sorted(set(nums))
idx = {v: i for i, v in enumerate(vals)}
st = SegmentTree(len(vals))
ans =0for x in nums:
l = bisect.bisect_left(vals, x-k)
r = bisect.bisect_left(vals, x)
best = st.query(l, r)
cur = best +1 st.update(idx[x], cur)
ans = max(ans, cur)
return ans
1
// Omitted for brevity. See Python for main logic.
1
// Omitted for brevity. See Python for main logic.