Skip to main content

Two Pointer

Make String a Subsequence Using Cyclic Increments Solution In C++/Java/Python/JS

Make String a Subsequence Using Cyclic Increments Problem Description:

You are given two 0-indexed strings str1 and str2.
In an operation, you select a set of indices in str1, and for each index i in the set, increment str1[i] to the next character cyclically. That is 'a' becomes 'b', 'b' becomes 'c', and so on, and 'z' becomes 'a'.i
Return true if it is possible to make str2 a subsequence of str1 by performing the operation at most once, and false otherwise.
Note: A subsequence of a string is a new string that is formed from the original string by deleting some (possibly none) of the characters without disturbing the relative positions of the remaining characters.
Make String a Subsequence Using Cyclic Increments-Problem-Description

Examples:

Input: str1 = "abc", str2 = "ad"
Output:
true
Explanation:
Select index 2 in str1.
Increment str1[2] to become 'd'.
Hence, str1 becomes "abd" and str2 is now a subsequence. Therefore, true is returned.

Input: str1 = "zc", str2 = "ad"
Output:
true
Explanation:
Select indices 0 and 1 in str1.
Increment str1[0] to become 'a'.
Increment str1[1] to become 'd'.
Hence, str1 becomes "ad" and str2 is now a subsequence. Therefore, true is returned.

Input: str1 = "ab", str2 = "d"
Output:
false
Explanation:
In this example, it can be shown that it is impossible to make str2 a subsequence of str1 using the operation at most once.
Therefore, false is returned.

Constraints:

1 <= str1.length <= 10⁵
1 <= str2.length <= 10⁵
str1 and str2 consist of only lowercase English letters.

Brute Force Approach

We’re given two strings — str1 and str2.
Our job is to check if it’s possible to make str2 a subsequence of str1 by performing at most one operation.

And what’s this operation?

We can pick a set of indices in str1 and increase each character at those indices by 1 alphabetically, cyclically.
That means:

  • ‘a’ → ‘b’, ‘b’ → ‘c’, and so on...
  • But here’s the catch — ‘z’ → ‘a’ (it wraps around like a circle!)

But here’s the big rule:

We are allowed to do this operation only once — so we can only change a chosen set of indices once. That’s it.

If we think freely, what’s the most obvious but honest way to check if we can make str2 a subsequence of str1 after changing some letters?

Well, a thought might pop up like:

“Hey, what if I just try all possible combinations of which characters I should increment in str1… and check if any of those modified versions make str2 a subsequence?”

That’s right. That’s exactly what this brute-force solution is doing.

We’re saying:

Let’s simulate all ways we could increment characters in str1, and for each such modified string, check if str2 becomes a subsequence.

Sounds good, but... how do we generate all combinations of indices where we might apply the increment?

Here’s the smart trick: we use bitmasks to represent all subsets of indices in str1.

Let’s say str1 = "abc", which has 3 characters.
That means we have 2³ = 8 possible combinations of positions we can choose to increment:

  • 000 → increment nothing → keep as is
  • 001 → increment index 0 only
  • 010 → increment index 1 only
  • 011 → increment indices 0 and 1
  • …and so on until…
  • 111 → increment all indices

Each bitmask from 0 to 2ⁿ-1 (where n is the length of str1) represents one way of selecting indices to increment.

That’s why we prefer bitmask — it gives us a clean and efficient way to try every subset of positions we could touch in one operation.

Now that we know which positions we want to increment (from our bitmask), how do we actually perform that increment?

Let’s say we’re dealing with character 'c'.

To move 'c' to 'd', we can use this clever formula:

(ch - 'a' + 1) % 26 + 'a'

Let’s break it:

  • 'c' - 'a' gives us 2
  • Add 1 → now we’re at 3
  • % 26 ensures we wrap around after 'z'
  • Add back 'a' to convert number back to character

So this turns 'c' to 'd', 'z' to 'a', etc.

We apply this formula only at the positions selected by our current bitmask.

So we’re building a new temporary version of str1, where only selected characters are bumped forward by one.

Now comes the big question: is str2 a subsequence of this modified str1?

This part is critical — we now need to compare the two strings.

But not like “Are they equal?” — no no.
We want to check:

“Can I find all the characters of str2, in the same order, inside the modified str1, possibly skipping some characters?”

This is called checking for a subsequence.

For example:

  • str1 = "abcd**"**
  • str2 = "bd"
    Yes! ‘b’ and ‘d’ appear in order — so it’s a subsequence.

We go character by character:

  • Start with the first char of str2
  • Scan through str1 until we find a match
  • Move to next char of str2, and keep going

If we reach the end of str2, we’ve found all its letters in order — so it is a subsequence.

This simple logic is done using two pointers — one for each string.

Take str1 = "abd" and str2 = "ad".

  • Start with 'a' from str2 → found at index 0 in str1
  • Next is 'd' → found at index 2 in str1 ( ahead of index 0)
  • All characters of str2 found in order → so "ad" is a subsequence of "abd".

This is exactly what the two-pointer method checks for.

Putting It All Together

So here’s what we do:

  1. Loop over all bitmask values from 0 to 2ⁿ - 1
    (Each represents one subset of indices to increment)
  2. For each bitmask:
    • Copy the original str1
    • Increment the characters at positions where the bitmask has 1
  3. Check if the modified string makes str2 a subsequence
  4. If yes — we’re done! Return true
  5. If we try all combinations and none work — return false

This approach tries every possible way to modify str1 and check if it works.

That means it can be very slow if str1 is large — because we’re checking 2ⁿ possibilities.
So it’s not the most optimal solution — but it guarantees correctness, and is a great way to build intuition for the problem.

Let's understand with an example:

Make String a Subsequence Using Cyclic Increments Example:

Let's dry run the brute-force approach on:

Input: str1 = "abc", str2 = "ad"

Step 1: str1 length = 3 → total bitmasks = 2³ = 8

We'll try all 8 bitmask combinations (from 000 to 111). Each bit means:
1 → increment that character, 0 → leave as is

Let's check each case: Mask = 000 (no changes)

  • str1 remains: "abc"
  • Is "ad" a subsequence of "abc"?
    → No ('d' not in "abc")

Mask = 001 (change index 0)

  • str1 becomes: "bbc"
  • Is "ad" a subsequence?
    → No

Mask = 010 (change index 1)

  • str1 becomes: "acc"
  • Is "ad" a subsequence?
    → No

Mask = 011 (change index 0 and 1)

  • str1 becomes: "bcc"
  • Is "ad" a subsequence?
    → No

Mask = 100 (change index 2)

  • str1 becomes: "abd"
  • Is "ad" a subsequence?
    → Yes (Found 'a', then 'd' in order)

Return true

So, as soon as we hit mask 100, we find a valid case → we return true and stop.

Steps to Implement the Solution:

  1. Get the length of str1 → call it n.
  2. Loop through all bitmask values from 0 to 2ⁿ - 1:
    • Each bitmask represents a unique subset of indices to increment.
  3. For each bitmask:
    • Make a copy of str1 (call it tempStr).
    • For each index i in str1:
      • If the i-th bit in the bitmask is 1:
        • Increment tempStr[i] by 1 alphabetically (with 'z' wrapping to 'a').
  4. Check if str2 is a subsequence of tempStr:
    • Use two pointers:
      • One on tempStr, one on str2.
      • Move both when characters match; otherwise, move only tempStr's pointer.
    • If all characters of str2 are found in order → it’s a subsequence.
  5. If any modified version of str1 makes str2 a subsequence:
    • Return true immediately
  6. If loop finishes without a match:
    • Return false

Make String a Subsequence Using Cyclic Increments Solution

Code Implementation / Make String a Subsequence Using Cyclic Increments leetcode Solution
1. Make String a Subsequence Using Cyclic Increments solution in C++ Try on Compiler
class Solution {
public:
    bool canMakeSubsequence(string str1, string str2) {
        
        // Get the length of str1
        int lengthStr1 = str1.length();

        // Loop through all possible combinations of character increments using bitmask
        for (int mask = 0; mask < (1 << lengthStr1); mask++) {

            // Create a temporary copy of str1 to apply transformations
            string temp = str1;

            // Apply character increments based on the current bitmask
            for (int str1Index = 0; str1Index < lengthStr1; str1Index++) {

                // If the bit at position str1Index is set, increment the character
                if (mask & (1 << str1Index)) {

                    // Perform cyclic increment: 'a'→'b', ..., 'z'→'a'
                    temp[str1Index] = (temp[str1Index] - 'a' + 1) % 26 + 'a';
                }
            }

            // Check if str2 is a subsequence of the modified string
            if (isSubsequence(temp, str2)) {
                return true;
            }
        }

        // If no modified string makes str2 a subsequence, return false
        return false;
    }

private:
    // Helper function to check if str2 is a subsequence of str1
    bool isSubsequence(string& str1, string& str2) {

        // Initialize pointers for both strings
        int str1Index = 0, str2Index = 0;
        int lengthStr1 = str1.size(), lengthStr2 = str2.size();

        // Traverse through both strings
        while (str1Index < lengthStr1 && str2Index < lengthStr2) {

            // If characters match, move pointer for str2
            if (str1[str1Index] == str2[str2Index]) {
                str2Index++;
            }

            // Always move pointer for str1
            str1Index++;
        }

        // If we've matched all characters of str2, it's a subsequence
        return str2Index == lengthStr2;
    }
};

2. Make String a Subsequence Using Cyclic Increments solution in Java Try on Compiler
class Solution {
    public boolean canMakeSubsequence(String str1, String str2) {

        // Get the length of str1
        int lengthStr1 = str1.length();

        // Loop through all possible combinations of character increments using bitmask
        for (int mask = 0; mask < (1 << lengthStr1); mask++) {

            // Create a temporary copy of str1 to apply transformations
            char[] temp = str1.toCharArray();

            // Apply character increments based on the current bitmask
            for (int i = 0; i < lengthStr1; i++) {

                // If the bit at position i is set, increment the character
                if ((mask & (1 << i)) != 0) {

                    // Perform cyclic increment: 'a'→'b', ..., 'z'→'a'
                    temp[i] = (char)((temp[i] - 'a' + 1) % 26 + 'a');
                }
            }

            // Check if str2 is a subsequence of the modified string
            if (isSubsequence(new String(temp), str2)) {
                return true;
            }
        }

        // If no modified string makes str2 a subsequence, return false
        return false;
    }

    // Helper function to check if str2 is a subsequence of str1
    private boolean isSubsequence(String str1, String str2) {
        
        // Initialize pointers for both strings
        int i = 0, j = 0;
        int n = str1.length(), m = str2.length();

        // Traverse through both strings
        while (i < n && j < m) {

            // If characters match, move pointer for str2
            if (str1.charAt(i) == str2.charAt(j)) {
                j++;
            }

            // Always move pointer for str1
            i++;
        }

        // If we've matched all characters of str2, it's a subsequence
        return j == m;
    }
}

3. Make String a Subsequence Using Cyclic Increments solution in Python Try on Compiler
class Solution:
    def canMakeSubsequence(self, str1, str2):

        # Get the length of str1
        n = len(str1)

        # Loop through all possible combinations of character increments using bitmask
        for mask in range(1 << n):

            # Create a list copy of str1 to apply transformations
            temp = list(str1)

            # Apply character increments based on the current bitmask
            for i in range(n):

                # If the bit at position i is set, increment the character
                if (mask >> i) & 1:

                    # Perform cyclic increment: 'a'→'b', ..., 'z'→'a'
                    temp[i] = chr((ord(temp[i]) - ord('a') + 1) % 26 + ord('a'))

            # Check if str2 is a subsequence of the modified string
            if self.isSubsequence("".join(temp), str2):
                return True

        # If no modified string makes str2 a subsequence, return false
        return False

    # Helper function to check if str2 is a subsequence of str1
    def isSubsequence(self, str1, str2):
        
        # Initialize pointers for both strings
        i = j = 0
        n, m = len(str1), len(str2)

        # Traverse through both strings
        while i < n and j < m:

            # If characters match, move pointer for str2
            if str1[i] == str2[j]:
                j += 1

            # Always move pointer for str1
            i += 1

        # If we've matched all characters of str2, it's a subsequence
        return j == m

4. Make String a Subsequence Using Cyclic Increments solution in Javascript Try on Compiler
/**
 * @param {string} str1
 * @param {string} str2
 * @return {boolean}
 */
var canMakeSubsequence = function(str1, str2) {
    // Get the length of str1
    const n = str1.length;

    // Loop through all possible combinations of character increments using bitmask
    for (let mask = 0; mask < (1 << n); mask++) {

        // Create an array copy of str1 to apply transformations
        let temp = str1.split('');

        // Apply character increments based on the current bitmask
        for (let i = 0; i < n; i++) {

            // If the bit at position i is set, increment the character
            if ((mask >> i) & 1) {

                // Perform cyclic increment: 'a'→'b', ..., 'z'→'a'
                temp[i] = String.fromCharCode((temp[i].charCodeAt(0) - 97 + 1) % 26 + 97);
            }
        }

        // Check if str2 is a subsequence of the modified string
        if (isSubsequence(temp.join(''), str2)) {
            return true;
        }
    }

    // If no modified version makes str2 a subsequence, return false
    return false;
};

// Helper function to check if str2 is a subsequence of str1
function isSubsequence(str1, str2) {
    
    // Initialize pointers for both strings
    let i = 0, j = 0;
    const n = str1.length, m = str2.length;

    // Traverse through both strings
    while (i < n && j < m) {

        // If characters match, move pointer for str2
        if (str1[i] === str2[j]) {
            j++;
        }

        // Always move pointer for str1
        i++;
    }

    // If all characters of str2 are matched, it's a subsequence
    return j === m;
}

Make String a Subsequence Using Cyclic Increments: Complexity Analysis

Time Complexity: O(2ⁿ * (n + m))

Let's break down the time complexity analysis of the brute-force solution

  1. For every combination of characters in str1, it either:That gives us 2 choices per character.
    • Leaves the character unchanged, or
    • Increments it once cyclically (e.g., 'z' → 'a').
  2. So, we generate all 2ⁿ combinations of increment/no-increment where n = str1.length.
  3. For each combination (modified string), we check if str2 is a subsequence of the modified string.

Let:

  • n = length of str1
  • m = length of str2

1. Outer loop using bitmasking

  • We go through all 2ⁿ masksO(2ⁿ)

2. Inner loop to build the modified string

  • For each bitmask, we iterate through str1 (length n) to apply possible increments → O(n)

3. Subsequence Check

  • To check if str2 is a subsequence of modified str1, we use two pointers → O(n + m) in worst case

Total Time Complexity: O(2ⁿ * (n + m))

Space Complexity: O(n)

  1. Auxiliary Space Complexity: O(1)
    Auxiliary space refers to the additional memory the algorithm requires, excluding the space occupied by the input.
    The extra space used — such as loop counters, masks, and temporary characters for manipulation — are all primitive types.
    We don’t create any large or dynamic data structures that scale with input size during computation.
    Therefore, the auxiliary space complexity is O(1).
  2. Total Space Complexity: O(n)
    Total space is the overall memory used by the algorithm, including both the input and any extra space needed during execution.
    We do create a temporary copy of the string str1 in each iteration (called temp) to apply character increments.
    This copy has a size proportional to n, where n = str1.length.
    No other significant space is used that depends on input size.

So, the total space complexity is O(n) due to the need to store the temporary modified version of the string.

Will Brute Force Work Against the Given Constraints? 

For the current solution, the time complexity is O(2ⁿ * (n + m)), where n is the length of the input string str1, and m is the length of str2.

Given the constraints 1 <= str1.length <= 10⁵ and 1 <= str2.length <= 10⁵, this means the algorithm could theoretically perform up to O(2ⁿ * (n + m)) operations in the worst-case scenario.

However, 2ⁿ grows exponentially with n. For example, if n = 20, there are already over 1 million (2²⁰ ≈ 1,048,576) combinations to check, which is quite large but still feasible with fast computers. But if n increases further, say to 30 or 40, the number of combinations becomes billions or trillions, which is practically impossible to compute within any reasonable time.

For n = 10⁵, 2ⁿ is unimaginably huge — far beyond any computer’s capacity to handle. This is why this brute force approach is not possible or feasible for large input sizes close to the upper constraint, and it would definitely result in Time Limit Exceeded (TLE) errors.

So, while the solution conceptually works, it only applies to very small strings or simplified test cases. For large inputs, more optimized approaches are necessary.

How to optimize it?

Let’s Begin: Remember That Brute Force?

Hey! In the previous brute-force solution, we tried every possible way of incrementing characters in str1 using bitmasking. That means for each character, we either kept it as-is or bumped it up by one (wrapping around ‘z’ to ‘a’). Then for every such possibility, we checked if str2 is a subsequence. Neat idea, but as we saw — it’s a bit like trying every key on a keyring until one works. It’s slow, especially if str1 is long.

So, what if we take a step back and ask:

"Do we really need to try all combinations?"

Make String a Subsequence Using Cyclic Increments Algorithm

Let’s remember what the operation allowed us to do:

  • We can choose a subset of characters from str1, and
  • Increment each chosen character by 1 (cyclically), but…
  • We can do this operation only once, so we must choose our subset wisely.

But here’s the clever trick:
We don’t need to simulate all those combinations.
Instead, we can just walk through both strings, and for each character in str1, check:

“Can this character — either as-is or if I increment it once — match the current character in str2?”

We’re not rearranging anything. We can only delete characters. That’s the definition of a subsequence.

So, we ask at each position in str1:

  • Is this character equal to str2[j]?
    → Great! We move to the next character in str2.
  • Or… if we increment this character by one (wrapping around after ‘z’), does it match str2[j]?
    → Still good! Move forward.

If either of those checks passes, we move the pointer in str2.
Otherwise, we skip and keep going through str1 — just like matching a pattern letter-by-letter, but allowing a one-step bump in characters.

Simply, we just walk through both strings once using two pointers:

  • i points to str1,
  • j points to str2.

At each step:

  • If str1[i] matches str2[j], we move both pointers ahead.
  • If str1[i] is just one step ahead in the alphabet (like 'a' → 'b', or 'z' → 'a'), we also allow it as a match and move both pointers.
  • Otherwise, we just move i to check the next character in str1.

We keep doing this until we either:

  • Find all characters of str2 in order → success
  • Or we run out of str1 characters → failure

We don’t try every combo. We just:

  • Walk through both strings in a single pass,
  • Check for match or possible one-step increment match.

That’s it. Super simple. Efficient. Clean.
And it scales beautifully even for huge strings because we’re doing only one pass over them.

Let us understand this with a video.

0:00
/0:41

Make String a Subsequence Using Cyclic Increments-Optimal-Approach

Let's understand with an example:

Make String a Subsequence Using Cyclic Increments Example:

Say:

  • str1 = "abc"
  • str2 = "ad"

Let’s simulate:

  • Start with i = 0, j = 0
    • str1[0] = ‘a’, str2[0] = ‘a’ → Match! → j++
  • i = 1, j = 1
    • str1[1] = ‘b’, str2[1] = ‘d’ → No match, and 'b'+1 = 'c' ≠ 'd' → skip
  • i = 2, j = 1
    • str1[2] = ‘c’, str2[1] = ‘d’
    • 'c'+1 = 'd' → Match! → j++

And boom — we reached the end of str2! That means str2 is a subsequence of modified str1, with at most one operation.

How to code it up:

  1. Initialize two pointers:
    • One for str1 (let’s call it i)
    • One for str2 (let’s call it j)
  2. Loop through str1 while both pointers are within bounds:
    • At each step, check if:
      • str1[i] is equal to str2[j], or
      • Incrementing str1[i] by 1 (cyclically from 'z' to 'a') matches str2[j].
  3. If either condition matches, increment the j pointer to move to the next character in str2.
  4. Always increment the i pointer to move through str1.
  5. After the loop, check if j reached the end of str2:
    • If yes → str2 is a valid subsequence → return true.
    • Otherwise → str2 could not be matched → return false.

Make String a Subsequence Using Cyclic Increments Solution

Code Implementation / Make String a Subsequence Using Cyclic Increments leetcode Solution
1. Make String a Subsequence Using Cyclic Increments solution in C++ Try on Compiler
class Solution {
public:
    bool canMakeSubsequence(string str1, string str2) {
        
        // Store the lengths of both strings
        int n = str1.size();
        int m = str2.size();

        // Initialize two pointers for both strings
        int i = 0;
        int j = 0;

        // Traverse both strings until one is fully processed
        while (i < n && j < m)
        {
            // Check if current characters match or match after a single cyclic increment
            if (str1[i] == str2[j] || (str1[i] - 'a' + 1) % 26 == (str2[j] - 'a'))
            {
                // Move to the next character in str2 if matched
                j++;
            }

            // Always move to the next character in str1
            i++;
        }

        // If all characters of str2 have been matched, return true
        if (j == m)
            return true;

        // Otherwise, return false
        return false;
    }
};

2. Make String a Subsequence Using Cyclic Increments solution in Java Try on Compiler
class Solution {
    public boolean canMakeSubsequence(String str1, String str2) {

        // Store the lengths of both strings
        int n = str1.length();
        int m = str2.length();

        // Initialize two pointers for both strings
        int i = 0;
        int j = 0;

        // Traverse both strings until one is fully processed
        while (i < n && j < m) {

            // Check if current characters match or match after a single cyclic increment
            if (str1.charAt(i) == str2.charAt(j) ||
                (str1.charAt(i) - 'a' + 1) % 26 == (str2.charAt(j) - 'a')) {
                    
                // Move to the next character in str2 if matched
                j++;
            }

            // Always move to the next character in str1
            i++;
        }

        // If all characters of str2 have been matched, return true
        if (j == m)
            return true;

        // Otherwise, return false
        return false;
    }
}

3. Make String a Subsequence Using Cyclic Increments solution in Python Try on Compiler
class Solution:
    def canMakeSubsequence(self, str1, str2):

        # Store the lengths of both strings
        n = len(str1)
        m = len(str2)

        # Initialize two pointers for both strings
        i = 0
        j = 0

        # Traverse both strings until one is fully processed
        while i < n and j < m:
            
            # Check if current characters match or match after a single cyclic increment
            if str1[i] == str2[j] or (ord(str1[i]) - ord('a') + 1) % 26 == (ord(str2[j]) - ord('a')):
                # Move to the next character in str2 if matched
                j += 1

            # Always move to the next character in str1
            i += 1

        # If all characters of str2 have been matched, return True
        if j == m:
            return True

        # Otherwise, return False
        return False

4. Make String a Subsequence Using Cyclic Increments solution in Javascript Try on Compiler
var canMakeSubsequence = function(str1, str2) {

    // Store the lengths of both strings
    let n = str1.length;
    let m = str2.length;

    // Initialize two pointers for both strings
    let i = 0;
    let j = 0;

    // Traverse both strings until one is fully processed
    while (i < n && j < m) {
        
        // Check if current characters match or match after a single cyclic increment
        if (str1[i] === str2[j] || (str1.charCodeAt(i) - 97 + 1) % 26 === (str2.charCodeAt(j) - 97)) {
            // Move to the next character in str2 if matched
            j++;
        }

        // Always move to the next character in str1
        i++;
    }

    // If all characters of str2 have been matched, return true
    if (j === m)
        return true;

    // Otherwise, return false
    return false;
};

Make String a Subsequence Using Cyclic Increments: Complexity Analysis

Time Complexity: O(n + m)

  • Let n be the length of str1, and m be the length of str2.
  • We use two pointers (i for str1, j for str2) and iterate through each string only once.
  • At each step, we compare one character from str1 with one from str2, and either move both or just i.
  • So in the worst case, we go through all characters of both strings once:

Total time: O(n + m)

Space Complexity: O(n + m)

  1. Auxiliary Space Complexity: O(1)
    Auxiliary space refers to the additional memory the algorithm requires, excluding the space occupied by the input.
    No extra space is used apart from a few primitive variables (i, j, n, m).
    There are no recursive calls, no extra data structures like arrays or hashmaps.
    So the space complexity is constant: O(1)
  2. Total Space Complexity: O(n + m)
    Total space is the overall memory used by the algorithm, including both the input and any extra space needed during execution.
    While auxiliary space is O(1), if the input strings count towards total space, then:
    str1 takes O(n) space.
    str2 takes O(m) space.

So the total space is O(n + m) if the inputs are included.

Similar Problems

This problem is a classic String manipulation challenge where we're asked to check if one string can be transformed into another in a limited way. By using the efficient Two Pointer technique, we can scan through both strings simultaneously to determine if a valid transformation leads to a subsequence match. This approach keeps the logic simple and runs in linear time.

Now that we have successfully tackled this problem, let's try similar problems.

Given two strings s and t, return true if s is a subsequence of t, or false otherwise.
A subsequence of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., "ace" is a subsequence of "abcde" while "aec" is not).

💡
Showcase your skills by joining LearnYard Technologies FZ-LLC as a Technical Content Writer. Apply now and inspire the next generation of learners—fill out the form: https://forms.gle/CGDsbGkcapSfvXKM8