Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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
dparray 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²).
