Program to Find the longest subsequence where the absolute difference between every adjacent element is at most k in Python.

Finding the longest subsequence where the absolute difference between every adjacent element is at most k is a dynamic programming problem that can be efficiently solved using a segment tree for range maximum queries.

So, if the input is like nums = [5, 6, 2, 1, ?6, 0, ?1] and k = 4, then the output will be 6.

Algorithm Overview

The approach uses coordinate compression and a segment tree to efficiently track the maximum subsequence length ending at each position ?

  • Sort the array to create coordinate mapping

  • For each element, find the range of valid previous elements (within k difference)

  • Query the maximum subsequence length in that range

  • Update the current position with the new maximum length

Implementation

import math, bisect

class Solution:
    def solve(self, nums, k):
        n = 2 ** int(math.log2(len(nums) + 1) + 1)
        segtree = [0] * 100000
        
        def update(i, x):
            i += n
            while i:
                segtree[i] = max(segtree[i], x)
                i //= 2
        
        def query(i, j):
            ans = -float("inf")
            i += n
            j += n + 1
            while i < j:
                if i % 2 == 1:
                    ans = max(ans, segtree[i])
                    i += 1
                if j % 2 == 1:
                    j -= 1
                    ans = max(ans, segtree[j])
                i //= 2
                j //= 2
            return ans
        
        # Coordinate compression
        snums = sorted(nums)
        index = {x: i for i, x in enumerate(snums)}
        ans = 0
        
        for x in nums:
            # Find valid range for previous elements
            lo = bisect.bisect_left(snums, x - k)
            hi = bisect.bisect_right(snums, x + k) - 1
            
            # Query maximum subsequence length in valid range
            count = query(lo, hi)
            if count == -float("inf"):
                count = 0
            
            # Update current position with new length
            update(index[x], count + 1)
            ans = max(ans, count + 1)
        
        return ans

# Test the solution
ob = Solution()
result = ob.solve([5, 6, 2, 1, -6, 0, -1], 4)
print("Longest subsequence length:", result)
Longest subsequence length: 6

How It Works

The segment tree maintains maximum subsequence lengths for coordinate-compressed positions. For each element ?

  1. Coordinate Compression: Map elements to indices in sorted order

  2. Range Query: Find elements within [x-k, x+k] range using binary search

  3. DP Update: Query maximum length in valid range and extend by 1

  4. Segment Tree Update: Store the new maximum length at current position

Example Walkthrough

For nums = [5, 6, 2, 1, ?6, 0, ?1] and k = 4 ?

  • Sorted array: [?6, ?1, 0, 1, 2, 5, 6]

  • Processing 5: valid range includes [1, 2], extends to length 3

  • Processing 6: valid range includes [2, 5], extends to length 4

  • The algorithm continues building the optimal subsequence

Time Complexity

The time complexity is O(n log n) where n is the length of the input array. The space complexity is O(n) for the segment tree and coordinate mapping.

Conclusion

This segment tree approach efficiently solves the longest subsequence problem by using coordinate compression and range maximum queries. The algorithm maintains optimal subsequence lengths while processing elements in their original order.

Updated on: 2026-03-25T13:41:16+05:30

541 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements