Check whether we can form string2 by deleting some characters from string1 without reordering the characters of any string - JavaScript

In this problem, we need to determine whether we can form string2 by removing some characters from string1 without changing the order of characters in either string. This is essentially checking if string2 is a subsequence of string1.

Understanding the Problem

We want to check if the second string can be formed from the first string while preserving character order. Let's look at some examples:

// Example 1: Can form "ale" from "apple"
let s1 = "apple";
let s2 = "ale";
console.log("Can form '" + s2 + "' from '" + s1 + "'?");
// Expected: true (a-p-p-l-e contains a-l-e in order)
Can form 'ale' from 'apple'?
// Example 2: Cannot form "pan" from "banana"  
let s3 = "banana";
let s4 = "pan";
console.log("Can form '" + s4 + "' from '" + s3 + "'?");
// Expected: false ('p' doesn't exist in "banana")
Can form 'pan' from 'banana'?

Algorithm Approach

We'll use a two-pointer technique:

  1. Initialize two pointers: one for string1 (i) and one for string2 (j)
  2. Iterate through both strings simultaneously
  3. When characters match, advance both pointers
  4. When they don't match, only advance the string1 pointer
  5. If we've matched all characters in string2, return true

Implementation

function canFormString(string1, string2) {
    let i = 0; // Pointer for string1
    let j = 0; // Pointer for string2

    // Continue until we've checked all of string2 or reached end of string1
    while (j < string2.length && i < string1.length) {
        if (string1[i] === string2[j]) {
            // Characters match - advance both pointers
            i++;
            j++;
        } else {
            // Characters don't match - only advance string1 pointer
            i++;
        }
    }

    // Return true if we found all characters of string2
    return j === string2.length;
}

// Test cases
console.log("Test 1:", canFormString("apple", "ale"));
console.log("Test 2:", canFormString("banana", "pan")); 
console.log("Test 3:", canFormString("hello world", "helo"));
console.log("Test 4:", canFormString("programming", "gramin"));
Test 1: true
Test 2: false
Test 3: true
Test 4: true

Step-by-Step Example

Let's trace through "apple" and "ale":

function canFormStringWithTrace(string1, string2) {
    let i = 0, j = 0;
    
    console.log("Checking if '" + string2 + "' can be formed from '" + string1 + "'");
    
    while (j < string2.length && i < string1.length) {
        console.log("Comparing '" + string1[i] + "' with '" + string2[j] + "'");
        
        if (string1[i] === string2[j]) {
            console.log("Match found! Advancing both pointers");
            i++;
            j++;
        } else {
            console.log("No match. Advancing string1 pointer only");
            i++;
        }
    }
    
    let result = j === string2.length;
    console.log("Result:", result);
    return result;
}

canFormStringWithTrace("apple", "ale");
Checking if 'ale' can be formed from 'apple'
Comparing 'a' with 'a'
Match found! Advancing both pointers
Comparing 'p' with 'l'
No match. Advancing string1 pointer only
Comparing 'p' with 'l'
No match. Advancing string1 pointer only
Comparing 'l' with 'l'
Match found! Advancing both pointers
Comparing 'e' with 'e'
Match found! Advancing both pointers
Result: true

Complexity Analysis

Complexity Type Value Explanation
Time Complexity O(m + n) We traverse each string at most once
Space Complexity O(1) Only using constant extra space for pointers

Conclusion

The two-pointer approach efficiently determines if one string is a subsequence of another in linear time. This solution maintains character order and works well for checking if string2 can be formed by deleting characters from string1.

Updated on: 2026-03-15T23:19:00+05:30

329 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements