What is a Subsequence in DSA? A Beginner-Friendly Guide
Oct 31, 2025 6 Min Read 587 Views
(Last Updated)
What makes a sequence of values meaningful in algorithms, order, or connection? That’s where the idea of a subsequence comes in. Unlike substrings that require elements to sit side by side, a subsequence in DSA simply asks you to keep the original order, even if you skip over some values.
It’s a small shift in definition, but one that shows up all over data structures and algorithms, especially in problems like Longest Common Subsequence (LCS), Longest Increasing Subsequence (LIS), and sequence pattern matching.
If you’ve ever wondered why some solutions use dynamic programming while others go with a greedy scan, understanding subsequence in DSA will start to make those decisions click. That is what you are going to learn in-depth about in this article. Let us get started!
Table of contents
- What is a Subsequence in DSA?
- Properties of Subsequence in DSA
- Working with Subsequences: Algorithms and Code
- Generating All Subsequences
- Checking If One String is a Subsequence of Another
- Longest Increasing Subsequence (LIS)
- Subsequence vs Substring
- Applications of Subsequences
- Conclusion
- FAQs
- What is a subsequence?
- How is a subsequence different from a substring?
- How do you check if one string is a subsequence of another?
- What is the Longest Common Subsequence (LCS)?
- How many subsequences does a sequence of length n have?
What is a Subsequence in DSA?

Think of a subsequence as a “filtered” version of a sequence where you keep the remaining elements in the same order. You simply pick some elements (possibly all or none) and delete the others, but never reorder the picks. Formally:
- Definition: A subsequence of a sequence is a new sequence obtained by deleting zero or more elements without changing the relative order of the remaining elements.
- Example: Given the sequence ⟨A,B,C,D,E,F⟩, one subsequence is ⟨A,B,D⟩ (by deleting C, E, F). In strings, if your string is “ABCDE”, subsequences include “ACE”, “BD”, “ABCDE” (the whole string), and even the empty string “”. For instance, “geeks” has subsequences like “gks”, “ees”, “geeks” (itself), and “”
- How to think about it: Imagine scanning through the original sequence and deciding for each element to either include it or skip it. Whatever you include (in order) becomes your subsequence. For example, if you start with “abcdef” and choose to keep a, c, e, you end up with the subsequence “ace”.
Properties of Subsequence in DSA

Here are some fundamental facts about subsequences that often come up in Data Structures and Algorithms:
- Self and Empty: Any sequence is trivially a subsequence of itself (keep all elements). Also, the empty sequence (no elements) is a subsequence of every sequence (just delete everything).
- Order Preserved: A subsequence must preserve original order. You cannot reorder elements; you can only drop them. For instance, from <A,B,A>, <A,A> is a valid subsequence (we kept the two A’s in order), but <A,A,B> is not (it changes the order).
- Transitivity: If X is a subsequence of Y, and Y is a subsequence of Z, then X is a subsequence of Z (deletions compose).
- Subsequence of Subsequence: If you take a subsequence and then take a subsequence of that, you still have a subsequence of the original sequence.
These properties highlight that subsequences are more general than substrings or subarrays (you can skip elements freely).
If you want to read more about how DSA paves the way for effective coding and its use cases, consider reading HCL GUVI’s Free Ebook: The Complete Data Structures and Algorithms Handbook, which covers the key concepts of Data Structures and Algorithms, including essential concepts, problem-solving techniques, and real MNC questions.
Working with Subsequences: Algorithms and Code
In practice, we often need to generate subsequences or test subsequence relationships, or solve problems like LCS/LIS. Below are some common algorithms and examples.
1. Generating All Subsequences
One common task is to list all subsequences of a string or array. The straightforward method is a backtracking (pick/don’t pick) recursion:
- Idea: For each element of the sequence, you have two choices: include it in the current subsequence or skip it. Recurse on the next element with both choices.
Example (Python code): The function below prints all subsequences of a string:
def generate_subsequences(s, index=0, current=""):
if index == len(s):
print(f"'{current}'")
return
# Include s[index] in the subsequence
generate_subsequences(s, index+1, current + s[index])
# Exclude s[index]
generate_subsequences(s, index+1, current)
# Example usage:
generate_subsequences("ab")
# Output (order may vary):
# '' (empty), 'b', 'a', 'ab'
- For input “ab”, this prints ”, ‘a’, ‘b’, and ‘ab’. Notice the empty string (no picks) and the full string “ab” (picking all) appear.
- Explanation: In the above code, current accumulates the chosen characters. On reaching the end (index == len(s)), we have one complete subsequence. We backtrack by choosing not to include the current character as well.
- Time Complexity: This method runs in O(2^n) time (and space) because it explores all subsequence combinations. It’s only practical for relatively small n.
2. Checking If One String is a Subsequence of Another
Another common problem is: given strings s1 and s2, check if s1 is a subsequence of s2. A classic linear-time solution uses two pointers:
- Two-pointer approach: Let i point into s1 (the smaller string) and j into s2 (the larger). Traverse s2 with j. Whenever s1[i] == s2[j], advance i. Always advance j. At the end, if i has reached the length of s1, all its characters were matched in order, so s1 is a subsequence. Otherwise, it’s not.
Example (Python code):
def is_subsequence(small, large):
i = 0
for ch in large:
if i < len(small) and small[i] == ch:
i += 1
return i == len(small)
# Example usage:
print(is_subsequence("AXY", "ADXCPY")) # True
print(is_subsequence("AXY", "YADXCP")) # False
- In the first example, all characters of “AXY” appear in “ADXCPY” in order, so it returns True; in the second, although all characters exist, their order is broken, so it returns False.
- Complexity: This runs in O(n+m) time (where n,m are string lengths) and O(1) extra space, which is optimal for this check.
3. Longest Increasing Subsequence (LIS)
The Longest Increasing Subsequence problem finds a subsequence of a sequence of numbers that is strictly increasing and as long as possible. For example, in the array [3, 10, 2, 1, 20], the LIS is [3, 10, 20] of length 3.
A simple DP solution (length O(n^2)) is:
def LIS_length(arr):
n = len(arr)
dp = [1]*n # dp[i] = length of LIS ending at i
for i in range(n):
for j in range(i):
if arr[j] < arr[i]:
dp[i] = max(dp[i], dp[j] + 1)
return max(dp) if arr else 0
For [3, 10, 2, 1, 20], this would compute dp = [1,2,1,1,3] and return 3. (There are more efficient O(n\log n) solutions, but the DP idea is straightforward.)
Subsequence vs Substring
It’s important to distinguish subsequences from substrings (or subarrays). The key difference is contiguity:
- Subsequence: A subsequence can skip elements. From “abcdef”, “ace” is a valid subsequence (we kept a, c, e in order).
- Substring/Subarray: A substring is a contiguous run of characters from the original string. E.g., for “abcdef”, “bcd” is a substring (positions 2–4), but “ace” is not a substring because it skips letters.
Applications of Subsequences

Subsequences pop up in many areas of computer science and real-world problems. Here are a few applications and domains that rely on subsequences:
- Bioinformatics (DNA Analysis): In genetics, DNA sequences are long strings of nucleotides. Researchers look for certain subsequences (motifs or genes) within genomes. Since DNA motifs need not be contiguous (there can be intervening bases), a subsequence search is useful.
- Text and Data Processing: Subsequence matching helps in text search and pattern recognition. For example, you might find non-contiguous word patterns in sentences or logs. GfG notes subsequences in text processing and NLP for extracting meaningful phrases.
- Speech and Signal Recognition: Audio or video signals can use subsequences to identify patterns. In speech recognition, phonemes (sound units) appear in order but can have background noise or gaps, so subsequence matching helps.
- Dynamic Programming Problems: Many classic algorithm problems are about subsequences. The Longest Common Subsequence (LCS) problem finds the longest sequence common to two strings. The Longest Increasing Subsequence (LIS) problem finds the longest increasing sequence within a sequence of numbers. Both problems preserve order but allow gaps, so they are subsequence problems (see below). In fact, in DSA interviews and challenges, LCS and LIS are very common.
- Financial and Pattern Analysis: Subsequence techniques can identify patterns in financial time-series or stock data (searching for trends). Similarly, pattern recognition in images often looks for subsequence-like patterns of features.
Overall, whenever you need to identify ordered patterns within larger data (strings, arrays, signals) but don’t require them to be contiguous, subsequences are the concept to use.
If you want a platform that actually teaches DSA in a structured, beginner-friendly way while also giving you practical coding experience, consider enrolling in HCL GUVI’s DSA for Programmers Course that is designed specifically for learners who want clarity instead of confusion. It explains concepts in simple terms and guides you from basics to advanced topics step-by-step.
Subsequences form a fundamental concept that appears in many basic algorithms and problems in DSA. Whenever you need to reason about maintaining order but allowing gaps (like matching patterns or finding order-respecting subsets), you are in the realm of subsequences.
If you’re serious about mastering DSA in software development and want to apply it in real-world scenarios, don’t miss the chance to enroll in HCL GUVI’s IITM Pravartak and MongoDB Certified Online AI Software Development Course. Endorsed with NSDC certification, this course adds a globally recognized credential to your resume, a powerful edge that sets you apart in the competitive job market.
Conclusion
In conclusion, subsequence in DSA is a simple concept with high leverage. They let you reason about ordered patterns, move from brute force to efficient two-pointer or DP solutions, and form the basis of classic problems like LCS and LIS.
If you take away two things from the article, let them be these: (1) subsequence ≠ substring, and (2) practice the two-pointer check and a DP LCS/LIS implementation to see the idea in code. That small investment will pay off whenever you face sequence problems in DSA. The key is to remember the order-preserving rule and that many efficient algorithms (like DP for LCS/LIS) rely on this property.
FAQs
1. What is a subsequence?
A subsequence is any sequence you can get by deleting zero or more characters/elements from the original while keeping the remaining items in the same order. It preserves order but not contiguity.
2. How is a subsequence different from a substring?
A substring (or subarray) must be contiguous; a subsequence can skip elements as long as the order stays the same. So every substring is a subsequence, but not every subsequence is a substring.
3. How do you check if one string is a subsequence of another?
Use a two-pointer scan: advance the pointer on the larger string and move the pointer on the smaller string only when characters match. If the smaller pointer reaches the end, it’s a subsequence — O(n+m) time.
4. What is the Longest Common Subsequence (LCS)?
LCS is the longest sequence that appears as a subsequence in two given sequences. It’s commonly solved with dynamic programming in O(m×n) time and used in diff tools and bioinformatics.
5. How many subsequences does a sequence of length n have?
There are 2^n subsequences in total (including the empty subsequence) because each element can be either kept or dropped. This exponential growth makes brute-force enumeration practical only for small n.



Did you enjoy this article?