BackmediumStringsMicrosoftAdobe

Bitmask Subset Energy Evaluator 5 Solution

Problem Statement

You are provided with two strings, s and t, where s represents a sequence of system events and t represents a required verification pattern. The goal is to determine if t is a subsequence of s. A subsequence is derived by deleting zero or more characters from s without changing the relative order of the remaining characters. This verification is critical for ensuring that specific event patterns occur in the correct order within a larger log stream.

Your task is to implement a function that returns true if t is a subsequence of s, and false otherwise. The solution must efficiently handle large input sizes by leveraging a linear scan approach, ensuring that each character in s is processed at most once. This guarantees optimal performance for real-time system monitoring applications where latency is a concern.

The input consists of two strings, s and t. The output is a boolean value indicating the result of the subsequence verification. You must ensure that your implementation correctly handles edge cases, such as empty strings and cases where t is longer than s.

Example 1
Input
s = "abcde", t = "ace"
Output
true

Explanation: Start with pointer `j = 0` for `t`. Iterate through `s`: 'a' matches `t[0]`, so `j` becomes 1. 'b' and 'c' do not match `t[1]` ('c'). 'c' matches `t[1]`, so `j` becomes 2. 'd' does not match `t[2]` ('e'). 'e' matches `t[2]`, so `j` becomes 3. Since `j` equals the length of `t` (3), return `true`.

Example 2
Input
s = "abcde", t = "aec"
Output
false

Explanation: Start with pointer `j = 0` for `t`. Iterate through `s`: 'a' matches `t[0]`, so `j` becomes 1. 'b' and 'c' do not match `t[1]` ('e'). 'd' does not match `t[1]`. 'e' matches `t[1]`, so `j` becomes 2. The end of `s` is reached, but `j` (2) is less than the length of `t` (3). Return `false`.

Example 3
Input
s = "", t = ""
Output
true

Explanation: Both strings are empty. The length of `t` is 0, so the condition `j == t.length` is immediately satisfied. Return `true`.

Example 4
Input
s = "ababab", t = "baba"
Output
true

Explanation: Start with `j = 0`. 'a' does not match `t[0]` ('b'). 'b' matches `t[0]`, `j=1`. 'a' matches `t[1]`, `j=2`. 'b' matches `t[2]`, `j=3`. 'a' matches `t[3]`, `j=4`. `j` equals `t.length` (4). Return `true`.

Constraints

  • 0 <= s.length <= 10^5
  • 0 <= t.length <= 10^5
  • s and t consist of lowercase English letters.
Live Compiler1 Free Run Available
Loading Editor...
Test Cases & Output
Click "Run" to test your 1 free compile trial!

🚀 Practice this problem

Run code, get AI hints & track streak

Sign Up Free

Bitmask Subset Energy Evaluator 5 — Problem Statement & Solution Guide

StringsMediumSubsequence Verification
TimeO(|s|+|t|)
|
SpaceO(1)

Problem Description

You are provided with two strings, s and t, where s represents a sequence of system events and t represents a required verification pattern. The goal is to determine if t is a subsequence of s. A subsequence is derived by deleting zero or more characters from s without changing the relative order of the remaining characters. This verification is critical for ensuring that specific event patterns occur in the correct order within a larger log stream.

Your task is to implement a function that returns true if t is a subsequence of s, and false otherwise. The solution must efficiently handle large input sizes by leveraging a linear scan approach, ensuring that each character in s is processed at most once. This guarantees optimal performance for real-time system monitoring applications where latency is a concern.

The input consists of two strings, s and t. The output is a boolean value indicating the result of the subsequence verification. You must ensure that your implementation correctly handles edge cases, such as empty strings and cases where t is longer than s.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Bitmask Subset Energy Evaluator 5"

medium

WHY DOES IT MATTER?

The two-pointer pattern is essential because it transforms an exponential or quadratic problem into a linear one, enabling real-time processing of massive data streams. It also demonstrates a fundamental algorithmic principle: when the problem constraints allow a greedy choice, a simple scan can be optimal.

OPTIMIZATION CHALLENGE

The core insight is that once a character of t is matched, all subsequent characters must appear later in s. This eliminates the need for backtracking or storing intermediate states, reducing both time and space complexity from exponential/DP to linear/constant.

REAL-WORLD CONNECTION

In distributed event tracing, you often need to confirm that a sequence of microservice calls follows a prescribed order. By treating each call as a character and the trace as a string, the two-pointer scan can quickly validate the order without reconstructing the entire call graph, saving bandwidth and latency.

When explaining this in an interview, emphasize the greedy invariant: matching the earliest possible occurrence of each t character can never preclude a valid subsequence. This reasoning is often the key to convincing the interviewer of the algorithm’s correctness.

COMPLEXITY AT A GLANCE

⏱ Time:O(|s|+|t|)
💾 Space:O(1)

Core Theory — Why This Approach?

The problem of determining whether string t is a subsequence of string s is a classic example of a linear-time two-pointer scan. A naive approach would attempt to generate all possible subsequences of s or use recursion to try every deletion, leading to exponential time complexity O(2^|s|) and impractical memory usage. Instead, the optimal paradigm treats the two strings as streams and advances a pointer through s only when a matching character in t is found. This greedy strategy guarantees that if a character in t can be matched later in s, it will be matched at the earliest possible position, preserving the relative order required for a subsequence. The algorithm runs in O(|s| + |t|) time and O(1) auxiliary space, making it suitable for very large inputs where s can be millions of characters long.

The key insight is that once a character of t is matched, all subsequent characters of t must appear after that position in s. Therefore, we never need to backtrack or store intermediate states; a single pass suffices. This pattern is a building block for many string-processing problems, such as pattern matching, edit distance, and longest common subsequence, where a linear scan with two indices can dramatically reduce complexity compared to dynamic programming.

In distributed systems, this technique is analogous to stream processing where each event is consumed once and decisions are made on the fly. By avoiding the construction of large intermediate data structures, the algorithm remains cache-friendly and can be parallelized across multiple cores when multiple queries are processed concurrently.

Interview Questions on This Problem

Q1How would you modify the subsequence check algorithm to handle multiple queries of `t` against the same `s` efficiently, as might be required in a real-time monitoring system?

Preprocess s to build a next-occurrence table: for each position and each character, store the next index where that character appears. This allows each query to run in O(|t|) time by jumping directly to the next match, reducing the overall time for many queries to O(|s|*alphabet + total|t|).

Q2A fintech platform needs to verify that a transaction pattern `t` appears as a subsequence in a log stream `s`. What edge cases should you consider to avoid false positives?

Handle empty strings (empty t is always a subsequence, empty s only if t is empty), case sensitivity, and non-ASCII characters. Also ensure that the algorithm correctly handles repeated characters in t that may appear multiple times in s but must maintain order.

Q3During a coding interview, you are asked to explain why a two-pointer approach is preferable over dynamic programming for this problem. What key points would you highlight?

Two-pointer runs in linear time with constant space, while DP would require O(|s|*|t|) time and space. The greedy nature of the two-pointer guarantees correctness because matching a character as early as possible cannot hurt future matches. This simplicity also reduces the risk of bugs and makes the solution easier to reason about under time pressure.

Examples

Example 1

Input

s = "abcde", t = "ace"

Output

true

Explanation: Start with pointer `j = 0` for `t`. Iterate through `s`: 'a' matches `t[0]`, so `j` becomes 1. 'b' and 'c' do not match `t[1]` ('c'). 'c' matches `t[1]`, so `j` becomes 2. 'd' does not match `t[2]` ('e'). 'e' matches `t[2]`, so `j` becomes 3. Since `j` equals the length of `t` (3), return `true`.

Example 2

Input

s = "abcde", t = "aec"

Output

false

Explanation: Start with pointer `j = 0` for `t`. Iterate through `s`: 'a' matches `t[0]`, so `j` becomes 1. 'b' and 'c' do not match `t[1]` ('e'). 'd' does not match `t[1]`. 'e' matches `t[1]`, so `j` becomes 2. The end of `s` is reached, but `j` (2) is less than the length of `t` (3). Return `false`.

Example 3

Input

s = "", t = ""

Output

true

Explanation: Both strings are empty. The length of `t` is 0, so the condition `j == t.length` is immediately satisfied. Return `true`.

Example 4

Input

s = "ababab", t = "baba"

Output

true

Explanation: Start with `j = 0`. 'a' does not match `t[0]` ('b'). 'b' matches `t[0]`, `j=1`. 'a' matches `t[1]`, `j=2`. 'b' matches `t[2]`, `j=3`. 'a' matches `t[3]`, `j=4`. `j` equals `t.length` (4). Return `true`.

Constraints

  • 0 <= s.length <= 10^5
  • 0 <= t.length <= 10^5
  • s and t consist of lowercase English letters.

Optimal Approach & Strategy

Use a two-pointer scan: iterate through s, advancing a pointer in t only on matches. This runs in O(|s|+|t|) time and O(1) space.

Brute Force Approach

A naive solution would generate all subsequences of s and check if t is among them, which takes exponential time and is infeasible for large strings.

Verified Code Solutions

JavaScript Solution
Time: O(|s|+|t|)
function solution(nums, bitmask) {
   let n = nums.length;
   let energy = 0;
   let i = 0;
   while (bitmask > 0) {
       if ((bitmask & 1) === 1) {
           energy += nums[i];
       }
       bitmask >>= 1;
       i++;
   }
   return energy;
}

Asked in Top Tech Interviews

MicrosoftAdobe

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.