Longest Increasing Subsequence in DSA C - Time & Space Complexity
We want to know how the time needed to find the longest increasing subsequence changes as the input list grows.
How does the number of steps grow when the list gets bigger?
Analyze the time complexity of the following code snippet.
int lengthOfLIS(int* nums, int numsSize) {
int* dp = malloc(numsSize * sizeof(int));
int maxLen = 1;
for (int i = 0; i < numsSize; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i] && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
}
}
if (dp[i] > maxLen) maxLen = dp[i];
}
free(dp);
return maxLen;
}
This code finds the length of the longest increasing subsequence in an array by checking all previous elements for each position.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops comparing each element with all previous elements.
- How many times: Outer loop runs n times; inner loop runs up to i times, so roughly n times on average.
For each new element, the code checks all earlier elements to update the subsequence length.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 100 checks (10 * 10) |
| 100 | About 10,000 checks (100 * 100) |
| 1000 | About 1,000,000 checks (1000 * 1000) |
Pattern observation: The number of operations grows roughly by the square of the input size.
Time Complexity: O(n²)
This means if the input size doubles, the time to run roughly quadruples.
[X] Wrong: "The algorithm runs in linear time because it just loops through the array once."
[OK] Correct: There is a nested loop inside the main loop, so the total steps multiply, making it slower than just one loop.
Understanding this time complexity helps you explain how your solution scales and shows you can analyze nested loops clearly.
"What if we used a binary search method inside the loop to find the position instead of checking all previous elements? How would the time complexity change?"
Practice
Solution
Step 1: Understand the LIS definition
The Longest Increasing Subsequence is a subsequence where every next number is strictly greater than the previous one.Step 2: Compare options with the definition
The longest subsequence where each number is larger than the previous one matches the definition exactly. Options B, C, and D do not describe LIS correctly.Final Answer:
The longest subsequence where each number is larger than the previous one -> Option AQuick Check:
LIS = longest increasing subsequence [OK]
- Confusing increasing with non-decreasing
- Thinking LIS means equal numbers
- Mixing up subsequence with substring
arr of size n?Solution
Step 1: Understand LIS initialization
Each element starts with LIS length 1 because each element alone is a subsequence.Step 2: Check code correctness
int lis[n]; for(int i=0; iFinal Answer:
int lis[n]; for(int i=0; i -> Option BQuick Check:
Initialize LIS array with 1 [OK]
- Using memset to set integers to 1 (wrong)
- Initializing LIS array with zeros
- Not initializing LIS array at all
arr = {10, 22, 9, 33, 21, 50, 41, 60}?
int arr[] = {10, 22, 9, 33, 21, 50, 41, 60};
int n = 8;
int lis[8];
for(int i=0; i arr[j] && lis[i] < lis[j] + 1) {
lis[i] = lis[j] + 1;
}
}
}
int max = lis[0];
for(int i=1; i max) max = lis[i];
}
printf("%d", max);Solution
Step 1: Calculate LIS values step-by-step
Start with lis = {1,1,1,1,1,1,1,1} - i=1: arr[1]=22 > arr[0]=10, lis[1]=max(1,1+1)=2 - i=2: arr[2]=9 no smaller than previous, lis[2]=1 - i=3: arr[3]=33 > 22 and 10, lis[3]=max(1,2+1)=3 - i=4: arr[4]=21 > 10 but <22, lis[4]=max(1,1+1)=2 - i=5: arr[5]=50 > 33, 22, 21, lis[5]=max(1,3+1)=4 - i=6: arr[6]=41 > 33, 22, 21, lis[6]=max(1,3+1)=4 - i=7: arr[7]=60 > 50, 41, lis[7]=max(1,4+1)=5Step 2: Find maximum LIS length
Maximum value in lis array is 5.Final Answer:
5 -> Option CQuick Check:
LIS length for given array = 5 [OK]
- Counting non-increasing subsequences
- Forgetting to update lis[i] only if condition met
- Mixing up indices in nested loops
int arr[] = {3, 10, 2, 1, 20};
int n = 5;
int lis[5];
for(int i=0; i arr[j] && lis[i] < lis[j] + 1) {
lis[i] = lis[j] + 1;
}
}
}
int max = lis[0];
for(int i=1; i max) max = lis[i];
}
printf("%d", max);Solution
Step 1: Check LIS array initialization
LIS array elements represent length of subsequence ending at each index. Each element alone forms subsequence of length 1, so initialize lis[i] = 1.Step 2: Analyze effect of initialization
Initializing lis[i] = 0 causes all comparisons lis[i] < lis[j] + 1 to fail or produce wrong results, leading to incorrect max LIS length.Final Answer:
LIS array should be initialized with 1, not 0 -> Option AQuick Check:
Initialize LIS array with 1 to avoid zero-length subsequences [OK]
- Initializing LIS array with zeros
- Changing comparison operators incorrectly
- Starting loops at wrong indices
arr = {5, 7, 4, 8, 6, 9}, write a C function to find the length of the Longest Increasing Subsequence using dynamic programming. What is the length of the LIS for this array?Solution
Step 1: Initialize LIS array with 1 for each element
lis = {1,1,1,1,1,1}Step 2: Update LIS values by comparing each element with previous ones
- i=1 (7): 7 > 5, lis[1] = max(1, 1+1) = 2 - i=2 (4): 4 > 5? No, lis[2] = 1 - i=3 (8): 8 > 5, lis[3] = max(1,1+1)=2; 8 > 7, lis[3] = max(2,2+1)=3; 8 > 4, lis[3] = max(3,1+1)=3 - i=4 (6): 6 > 5, lis[4] = max(1,1+1)=2; 6 > 7? No; 6 > 4, lis[4] = max(2,1+1)=2; 6 > 8? No - i=5 (9): 9 > 5, lis[5] = max(1,1+1)=2; 9 > 7, lis[5] = max(2,2+1)=3; 9 > 4, lis[5] = max(3,1+1)=3; 9 > 8, lis[5] = max(3,3+1)=4; 9 > 6, lis[5] = max(4,2+1)=4Step 3: Find maximum LIS length
Maximum lis value is 4.Final Answer:
4 -> Option DQuick Check:
LIS length for given array = 4 [OK]
- Not updating LIS correctly for all previous elements
- Confusing subsequence with substring
- Forgetting to initialize LIS array with 1
Ready to prove it?
Pass the test and this pattern moves unknown
