Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Longest Increasing Subsequence and Related Dynamic Programming Problems

Tech May 11 3

LeetCode 300: Longest Increasing Subsequence

Given an integer array nums, find the length of the longest strictly increasing subsequence.

A subsequence is a sequence derived from an array by deleting some or no elements without changing the order of remaining elements.

Dynamic Programming Approach

Define dp[i] as the length of the longest increasing subsequence ending at index i. For each position i, we need to check all previous positions j (where j < i) to findd valid transitions.

Recurrence Relation:

  • If nums[i] > nums[j], then dp[i] = max(dp[i], dp[j] + 1)
  • Otherwise, nums[i] cannot extend the subsequence ending at j

Implementation:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if (nums.size() <= 1) return nums.size();
        
        vector<int> dp(nums.size(), 1);
        int maxLength = 0;
        
        for (int i = 1; i < nums.size(); i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = max(dp[i], dp[j] + 1);
                }
            }
            maxLength = max(maxLength, dp[i]);
        }
        return maxLength;
    }
};

Time Complexity: O(n²) where n is the array length Space Complexity: O(n)


LeetCode 674: Longest Continuous Increasing Subsequence

Given an integer array nums, find the length of the longest continuous increasing subsequence.

The key difference from the previous problem: this subsequence must be continuous (contiguous in the array).

Otpimized Approach

Since continuity is required, we only need to compare adjacent elements. This eliminates the need for nested loops.

Implementation:

class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        if (nums.empty()) return 0;
        
        int maxLength = 1;
        int currentLength = 1;
        
        for (int i = 1; i < nums.size(); i++) {
            if (nums[i] > nums[i - 1]) {
                currentLength++;
            } else {
                currentLength = 1;
            }
            maxLength = max(maxLength, currentLength);
        }
        return maxLength;
    }
};

Time Complexity: O(n) Space Complexity: O(1)


LeetCode 718: Maximum Length of Repeated Subarray

Given two integer arrays nums1 and nums2, return the length of the longest common subarray (contiguous subarray) found in both arrays.

Dynamic Programming Approach

This is a 2D DP problem. Define dp[i][j] as the length of the longest common subarray ending at nums1[i-1] and nums2[j-1].

Recurrence Relation:

  • If nums1[i-1] == nums2[j-1], then dp[i][j] = dp[i-1][j-1] + 1
  • Otherwise, dp[i][j] = 0 (subarrays must end at current positions)

Implementation:

class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size(), n = nums2.size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
        
        int maxLength = 0;
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (nums1[i - 1] == nums2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                    maxLength = max(maxLength, dp[i][j]);
                }
            }
        }
        return maxLength;
    }
};

Time Complexity: O(m × n) Space Complexity: O(m × n)

Space-Optimized Version

Since we only need the previous diagonal value, we can optimize space to O(n):

class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size(), n = nums2.size();
        vector<int> prev(n + 1, 0), curr(n + 1, 0);
        
        int maxLength = 0;
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (nums1[i - 1] == nums2[j - 1]) {
                    curr[j] = prev[j - 1] + 1;
                    maxLength = max(maxLength, curr[j]);
                } else {
                    curr[j] = 0;
                }
            }
            swap(prev, curr);
        }
        return maxLength;
    }
};

Summary

Problem Key Characteristic Time Space
300. LIS Non-contiguous subsequence O(n²) O(n)
674. LCIS Contiguous subsequence O(n) O(1)
718. Repeated Subarray Contiguous in both arrays O(m×n) O(min(m,n))

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.