Bird
Raised Fist0
DSA Rustprogramming~10 mins

Longest Increasing Subsequence in DSA Rust - Execution Trace

Choose your learning style10 modes available
Concept Flow - Longest Increasing Subsequence
Start with array
↓
Initialize dp array with 1s
↓
For each element i
↓
Check all elements j < i
↓
If arr[j
↓
Update dp[i
↓
Repeat for all i
↓
Find max value in dp
↓
Longest Increasing Subsequence length found
We start with the array, create a dp array to store LIS lengths ending at each index, update dp by checking previous smaller elements, then find the maximum dp value as the LIS length.
Execution Sample
DSA Rust
let arr = [10, 9, 2, 5, 3, 7, 101, 18];
let mut dp = vec![1; arr.len()];
for i in 1..arr.len() {
    for j in 0..i {
        if arr[j] < arr[i] {
            dp[i] = dp[i].max(dp[j] + 1);
        }
    }
}
let lis = *dp.iter().max().unwrap();
println!("{}", lis);
This code calculates the length of the longest increasing subsequence in the array.
Execution Table
StepOperationIndex iIndex jCondition arr[j]<arr[i]dp Array StateAction Taken
1Initialize dp---[1, 1, 1, 1, 1, 1, 1, 1]Set all dp values to 1
2i=1, j=010arr[0]=10 < arr[1]=9? No[1, 1, 1, 1, 1, 1, 1, 1]No update
3i=2, j=020arr[0]=10 < arr[2]=2? No[1, 1, 1, 1, 1, 1, 1, 1]No update
4i=2, j=121arr[1]=9 < arr[2]=2? No[1, 1, 1, 1, 1, 1, 1, 1]No update
5i=3, j=030arr[0]=10 < arr[3]=5? No[1, 1, 1, 1, 1, 1, 1, 1]No update
6i=3, j=131arr[1]=9 < arr[3]=5? No[1, 1, 1, 1, 1, 1, 1, 1]No update
7i=3, j=232arr[2]=2 < arr[3]=5? Yes[1, 1, 1, 2, 1, 1, 1, 1]dp[3] = max(1, dp[2]+1)=2
8i=4, j=040arr[0]=10 < arr[4]=3? No[1, 1, 1, 2, 1, 1, 1, 1]No update
9i=4, j=141arr[1]=9 < arr[4]=3? No[1, 1, 1, 2, 1, 1, 1, 1]No update
10i=4, j=242arr[2]=2 < arr[4]=3? Yes[1, 1, 1, 2, 2, 1, 1, 1]dp[4] = max(1, dp[2]+1)=2
11i=4, j=343arr[3]=5 < arr[4]=3? No[1, 1, 1, 2, 2, 1, 1, 1]No update
12i=5, j=050arr[0]=10 < arr[5]=7? No[1, 1, 1, 2, 2, 1, 1, 1]No update
13i=5, j=151arr[1]=9 < arr[5]=7? No[1, 1, 1, 2, 2, 1, 1, 1]No update
14i=5, j=252arr[2]=2 < arr[5]=7? Yes[1, 1, 1, 2, 2, 2, 1, 1]dp[5] = max(1, dp[2]+1)=2
15i=5, j=353arr[3]=5 < arr[5]=7? Yes[1, 1, 1, 2, 2, 3, 1, 1]dp[5] = max(2, dp[3]+1)=3
16i=5, j=454arr[4]=3 < arr[5]=7? Yes[1, 1, 1, 2, 2, 3, 1, 1]dp[5] = max(3, dp[4]+1)=3
17i=6, j=060arr[0]=10 < arr[6]=101? Yes[1, 1, 1, 2, 2, 3, 2, 1]dp[6] = max(1, dp[0]+1)=2
18i=6, j=161arr[1]=9 < arr[6]=101? Yes[1, 1, 1, 2, 2, 3, 2, 1]dp[6] = max(2, dp[1]+1)=2
19i=6, j=262arr[2]=2 < arr[6]=101? Yes[1, 1, 1, 2, 2, 3, 2, 1]dp[6] = max(2, dp[2]+1)=2
20i=6, j=363arr[3]=5 < arr[6]=101? Yes[1, 1, 1, 2, 2, 3, 3, 1]dp[6] = max(2, dp[3]+1)=3
21i=6, j=464arr[4]=3 < arr[6]=101? Yes[1, 1, 1, 2, 2, 3, 3, 1]dp[6] = max(3, dp[4]+1)=3
22i=6, j=565arr[5]=7 < arr[6]=101? Yes[1, 1, 1, 2, 2, 3, 4, 1]dp[6] = max(3, dp[5]+1)=4
23i=7, j=070arr[0]=10 < arr[7]=18? Yes[1, 1, 1, 2, 2, 3, 4, 2]dp[7] = max(1, dp[0]+1)=2
24i=7, j=171arr[1]=9 < arr[7]=18? Yes[1, 1, 1, 2, 2, 3, 4, 2]dp[7] = max(2, dp[1]+1)=2
25i=7, j=272arr[2]=2 < arr[7]=18? Yes[1, 1, 1, 2, 2, 3, 4, 2]dp[7] = max(2, dp[2]+1)=2
26i=7, j=373arr[3]=5 < arr[7]=18? Yes[1, 1, 1, 2, 2, 3, 4, 3]dp[7] = max(2, dp[3]+1)=3
27i=7, j=474arr[4]=3 < arr[7]=18? Yes[1, 1, 1, 2, 2, 3, 4, 3]dp[7] = max(3, dp[4]+1)=3
28i=7, j=575arr[5]=7 < arr[7]=18? Yes[1, 1, 1, 2, 2, 3, 4, 4]dp[7] = max(3, dp[5]+1)=4
29i=7, j=676arr[6]=101 < arr[7]=18? No[1, 1, 1, 2, 2, 3, 4, 4]No update
30Find max in dp---[1, 1, 1, 2, 2, 3, 4, 4]Max dp value is 4
31End---[1, 1, 1, 2, 2, 3, 4, 4]LIS length = 4
💡 All elements processed, dp array fully updated, maximum dp value found as LIS length
Variable Tracker
VariableStartAfter Step 7After Step 11After Step 16After Step 22After Step 29Final
dp[1,1,1,1,1,1,1,1][1,1,1,2,1,1,1,1][1,1,1,2,2,1,1,1][1,1,1,2,2,3,1,1][1,1,1,2,2,3,4,1][1,1,1,2,2,3,4,4][1,1,1,2,2,3,4,4]
i034567End
j-24566-
Key Moments - 3 Insights
Why do we initialize all dp values to 1 at the start?
Each element alone is an increasing subsequence of length 1, so dp starts with 1 for all indices (see Step 1 in execution_table).
Why do we only update dp[i] when arr[j] < arr[i]?
Because the subsequence must be strictly increasing, so only previous smaller elements can extend the subsequence (see Steps 7, 10, 15).
How do we find the final longest increasing subsequence length?
After filling dp, the maximum value in dp is the length of the longest increasing subsequence (see Step 30).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at Step 7. What is the dp array state after this step?
A[1, 1, 1, 1, 1, 1, 1, 1]
B[1, 1, 1, 2, 1, 1, 1, 1]
C[1, 2, 1, 2, 1, 1, 1, 1]
D[1, 1, 2, 2, 1, 1, 1, 1]
💡 Hint
Check the dp Array State column at Step 7 in execution_table.
At which iteration i does dp[6] first update to 4?
AStep 22
BStep 18
CStep 20
DStep 16
💡 Hint
Look at the Action Taken column for dp[6] updates in execution_table.
If the array was strictly decreasing, what would be the final dp array?
AIncreasing sequence from 1 to n
BAll zeros
CAll 1s
DRandom values
💡 Hint
Refer to variable_tracker and key_moments about dp initialization and updates.
Concept Snapshot
Longest Increasing Subsequence (LIS):
- Use dp array where dp[i] = length of LIS ending at i
- Initialize dp with 1s (each element alone)
- For each i, check all j < i: if arr[j] < arr[i], dp[i] = max(dp[i], dp[j]+1)
- Result is max value in dp
- Time complexity: O(n^2)
Full Transcript
Longest Increasing Subsequence finds the longest strictly increasing sequence inside an array. We create a dp array where each position starts at 1, meaning the smallest subsequence is the element itself. We then check for each element all previous elements smaller than it and update dp[i] to the longest subsequence length found plus one. After processing all elements, the maximum value in dp is the length of the longest increasing subsequence. This method uses nested loops and runs in quadratic time.

Practice

(1/5)
1. What does the Longest Increasing Subsequence (LIS) problem ask for in a given list of numbers?
easy
A. The longest sequence where each number is larger than the previous one
B. The longest sequence where each number is smaller than the previous one
C. The longest sequence of equal numbers
D. The shortest sequence containing all numbers

Solution

  1. Step 1: Understand the LIS definition

    The Longest Increasing Subsequence is the longest part of the list where every next number is bigger than the one before.
  2. Step 2: Compare options with definition

    The longest sequence where each number is larger than the previous one matches the definition exactly. Other options describe different sequences.
  3. Final Answer:

    The longest sequence where each number is larger than the previous one -> Option A
  4. Quick Check:

    LIS = longest increasing sequence [OK]
Hint: LIS means strictly increasing sequence length [OK]
Common Mistakes:
  • Confusing increasing with decreasing sequences
  • Thinking LIS means equal numbers
  • Mixing LIS with shortest sequences
2. Which Rust code snippet correctly initializes a vector to store LIS lengths for each element in a list named nums?
easy
A. let mut lis = vec![0; nums.len()];
B. let mut lis = vec![1; nums.len()];
C. let lis = vec![0; nums.len()];
D. let lis = vec![1; nums.len()];

Solution

  1. Step 1: Understand LIS initialization

    Each element starts with LIS length 1 because the smallest subsequence includes the element itself.
  2. Step 2: Check Rust syntax for mutable vector

    We need a mutable vector to update LIS values, so mut is required. The vector should be initialized with 1s.
  3. Final Answer:

    let mut lis = vec![1; nums.len()]; -> Option B
  4. Quick Check:

    Mutable vector with 1s = let mut lis = vec![1; nums.len()]; [OK]
Hint: LIS lengths start at 1, vector must be mutable [OK]
Common Mistakes:
  • Initializing with zeros instead of ones
  • Forgetting mut keyword for updates
  • Using immutable vector when updates needed
3. What is the output of the following Rust code that calculates the length of the LIS for nums = vec![10, 9, 2, 5, 3, 7, 101, 18]?
fn length_of_lis(nums: Vec<i32>) -> usize {
    let n = nums.len();
    let mut lis = vec![1; n];
    for i in 1..n {
        for j in 0..i {
            if nums[i] > nums[j] {
                lis[i] = lis[i].max(lis[j] + 1);
            }
        }
    }
    *lis.iter().max().unwrap()
}

fn main() {
    let nums = vec![10, 9, 2, 5, 3, 7, 101, 18];
    println!("{}", length_of_lis(nums));
}
medium
A. 4
B. 5
C. 3
D. 6

Solution

  1. Step 1: Trace LIS calculation for each element

    Starting with lis = [1,1,1,1,1,1,1,1]. - i=1: nums[1]=9 < 10, no update - i=2: nums[2]=2 < previous, no update - i=3: nums[3]=5 > 2, lis[3]=max(1, lis[2]+1)=2 - i=4: nums[4]=3 > 2, lis[4]=2 - i=5: nums[5]=7 > 5 and 3, lis[5]=max(1, lis[3]+1=3, lis[4]+1=3)=3 - i=6: nums[6]=101 > all previous, lis[6]=max(1, lis[5]+1=4, others less)=4 - i=7: nums[7]=18 > 7, lis[7]=max(1, lis[5]+1=4)=4
  2. Step 2: Find maximum LIS value

    The maximum value in lis is 4, which is the length of the longest increasing subsequence.
  3. Final Answer:

    4 -> Option A
  4. Quick Check:

    LIS length = 4 [OK]
Hint: Trace LIS array updates carefully for each element [OK]
Common Mistakes:
  • Counting non-increasing sequences
  • Forgetting to update lis[i] with max value
  • Misreading the nested loops
4. Identify the bug in this Rust function that attempts to compute the LIS length:
fn length_of_lis(nums: Vec<i32>) -> usize {
    let n = nums.len();
    let mut lis = vec![1; n];
    for i in 0..n {
        for j in 0..i {
            if nums[i] < nums[j] {
                lis[i] = lis[i].max(lis[j] + 1);
            }
        }
    }
    *lis.iter().max().unwrap()
}
What is the error?
medium
A. The function should return the sum of lis instead of max
B. The vector lis should be initialized with zeros instead of ones
C. The outer loop should start from 1 instead of 0
D. The comparison should be nums[i] > nums[j] instead of nums[i] < nums[j]

Solution

  1. Step 1: Analyze the comparison condition

    The LIS requires increasing order, so we must check if nums[i] > nums[j]. The code incorrectly uses nums[i] < nums[j], which finds decreasing sequences.
  2. Step 2: Confirm other parts are correct

    Initialization with ones and returning max are correct. Starting outer loop at 0 is valid but less efficient.
  3. Final Answer:

    The comparison should be nums[i] > nums[j] instead of nums[i] < nums[j] -> Option D
  4. Quick Check:

    Correct comparison is > for LIS [OK]
Hint: Check comparison signs for increasing sequences [OK]
Common Mistakes:
  • Using less than instead of greater than
  • Initializing lis with zeros
  • Returning sum instead of max
5. Given a list nums = vec![3, 10, 2, 1, 20], how would you modify the LIS algorithm to also return the actual longest increasing subsequence, not just its length?
hard
A. Sort the list first, then find LIS length on sorted list
B. Use a stack to push elements and pop when sequence breaks
C. Keep a predecessor array to track previous indices and reconstruct the sequence after computing LIS lengths
D. Return the maximum value in nums as the LIS length and sequence

Solution

  1. Step 1: Understand LIS length vs sequence

    Length calculation only tracks counts. To get the sequence, we must remember which elements lead to current LIS values.
  2. Step 2: Use predecessor array for reconstruction

    Maintain an array storing the index of the previous element in the LIS for each position. After LIS lengths are computed, backtrack from the max index to build the sequence.
  3. Step 3: Reject incorrect options

    Sorting changes order, invalid for LIS. Stack method is not standard for LIS. Returning max value is incorrect.
  4. Final Answer:

    Keep a predecessor array to track previous indices and reconstruct the sequence after computing LIS lengths -> Option C
  5. Quick Check:

    Predecessor array enables LIS reconstruction [OK]
Hint: Track previous indices to rebuild LIS sequence [OK]
Common Mistakes:
  • Sorting input before LIS calculation
  • Confusing stack usage with LIS logic
  • Returning max element instead of sequence
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard