Program to find number of increasing subsequences of size k in Python

Given a list of numbers and a value k, we need to find the number of strictly increasing subsequences of size k. A subsequence maintains the relative order of elements but doesn't need to be contiguous.

So, if the input is like nums = [2, 3, 4, 1] and k = 2, then the output will be 3, as we have the subsequences of size 2: [2, 3], [3, 4], [2, 4].

Approach Using Dynamic Programming

We use dynamic programming where dp[i] represents the number of increasing subsequences of current length ending at position i ?

Algorithm Steps

  • Initialize dp array with 1s (each element forms a subsequence of length 1)
  • For each length from 2 to k, update the dp array
  • For each position j, count how many smaller elements come before it
  • Return the sum of all dp values modulo 10^9 + 7

Implementation

def count_increasing_subsequences(nums, k):
    m = 10 ** 9 + 7
    dp = [1] * len(nums)
    
    # Build subsequences of length 2, 3, ..., k
    for length in range(k - 1):
        new_dp = [0] * len(nums)
        
        for j in range(len(nums)):
            for i in range(j):
                if nums[i] < nums[j]:
                    new_dp[j] = (new_dp[j] + dp[i]) % m
        
        dp = new_dp
    
    return sum(dp) % m

# Test the function
nums = [2, 3, 4, 1]
k = 2
result = count_increasing_subsequences(nums, k)
print(f"Number of increasing subsequences of size {k}: {result}")
Number of increasing subsequences of size 2: 3

How It Works

Let's trace through the example with nums = [2, 3, 4, 1] and k = 2 ?

def count_with_trace(nums, k):
    m = 10 ** 9 + 7
    dp = [1] * len(nums)
    print(f"Initial dp (length 1): {dp}")
    
    for length in range(k - 1):
        new_dp = [0] * len(nums)
        
        for j in range(len(nums)):
            for i in range(j):
                if nums[i] < nums[j]:
                    new_dp[j] += dp[i]
                    print(f"nums[{i}]={nums[i]} < nums[{j}]={nums[j]}, new_dp[{j}] = {new_dp[j]}")
        
        dp = new_dp
        print(f"dp after length {length + 2}: {dp}")
    
    return sum(dp) % m

nums = [2, 3, 4, 1]
k = 2
result = count_with_trace(nums, k)
print(f"Total: {result}")
Initial dp (length 1): [1, 1, 1, 1]
nums[0]=2 < nums[1]=3, new_dp[1] = 1
nums[0]=2 < nums[2]=4, new_dp[2] = 1
nums[1]=3 < nums[2]=4, new_dp[2] = 2
dp after length 2: [0, 1, 2, 0]
Total: 3

Example with Larger k

# Test with k = 3
nums = [1, 2, 3, 4, 5]
k = 3
result = count_increasing_subsequences(nums, k)
print(f"Subsequences of size {k} in {nums}: {result}")

# All possible increasing subsequences of size 3:
# [1,2,3], [1,2,4], [1,2,5], [1,3,4], [1,3,5], [1,4,5]
# [2,3,4], [2,3,5], [2,4,5], [3,4,5]
print("Expected: 10")
Subsequences of size 3 in [1, 2, 3, 4, 5]: 10
Expected: 10

Time and Space Complexity

  • Time Complexity: O(k × n²) where n is the length of nums
  • Space Complexity: O(n) for the dp array

Conclusion

This dynamic programming solution efficiently counts increasing subsequences by building from smaller lengths to the target length k. The approach uses modular arithmetic to handle large results and has a time complexity of O(k × n²).

Updated on: 2026-03-25T13:32:11+05:30

556 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements