Problem Statement:
Given a string s, the "type" of the string is defined by its first and last characters. For example, if s = "babdcaac", the type is "bc" (starts with 'b' and ends with 'c').
You can perform operations on the string to reduce its size, where one operation is equal to removing one character from the ends (effectively yielding a contiguous substring of the original string). Your goal is to maximize the number of operations performed such that the resulting string has the same type as the original string s.
(Note: Maximizing the operations is equivalent to finding the minimum length contiguous substring that starts with s[0] and ends with s[n-1]).
Example:
s = "babdcaac"
Valid resulting strings of type "bc" and their operations:
The maximum number of operations performed to yield a valid string is 5.
Problem Statement:
You are given a string data of lowercase English letters and a list of queries. There are two types of queries to process:
Return an array containing the results of all Type 2 queries.
Example:
data = "abfdpbp"
queries = [[2, 3, 6], [1, 5, 8], [2, 1, 2], [1, 4, 1], [1, 7, 4], [2, 1, 7]]
Output: [4, 2, 5]
Problem1-> Maximize Product Operations Solution
Topics Involved / Prerequisites
String Traversal
Two Pointers / Index Tracking
Overview
We need to find the shortest contiguous substring that begins with the original first character and ends with the original last character.
By iterating through the string, we can track the most recent index where the required starting character appeared. Whenever we encounter the required ending character, we calculate the substring length from that most recent start and keep the minimum.
Approach
1. Identifying the Targets
The "type" of the string is strictly defined by s[0] and s[n-1]. These are our target starting and ending characters. Our goal is to find the absolute shortest distance between any valid appearance of this start character and a subsequent appearance of this end character.
2. Tracking and Minimizing
We loop through the string from left to right, maintaining a lastSeenStart index. Every time we see our target start character, we update this index to the current position, ensuring it is as far right (and thus as close to the upcoming end character) as possible. If the current character is our target end character, and we have safely seen a start character previously, we calculate the length: current_index - lastSeenStart + 1. We track the minimum of these lengths. The maximum operations we can perform is simply the original length minus this minimum valid length.
Time Complexity
Problem2 -> Distinct Characters Query Solution
Topics Involved / Prerequisites
Segment Trees
Bit Manipulation (Bitmasks)
Range Queries
Overview
Since the string only contains lowercase English letters, any substring's unique characters can be perfectly represented as a 26-bit integer mask. A Segment Tree allows us to efficiently manage these bitmasks, where each parent node is simply the bitwise OR of its two children. This provides rapid point updates to change characters and rapid range queries to count the distinct set bits in any given segment.
Approach
1. The Bitmask Representation Instead of using heavy Hash Sets, we use a single 32-bit integer. If the character is 'a', we set the 0th bit (
1 << 0). If it's 'c', we set the 2nd bit (1 << 2). When we combine two segments of a string together, the unique characters of the combined string is just the bitwise OR (|) of their individual integer masks.2. The Segment Tree We build a Segment Tree where every leaf node holds the bitmask for a single character.
Updates (Type 1): We navigate down to the leaf representing
pos, update its bitmask to the new characterval, and then recalculate the parent nodes on the way back up using the bitwise OR operation.Queries (Type 2): We fetch the combined bitwise OR mask for the exact range
[L, R]. Once we have the final mask, we simply count how many bits are set to1(using a built-in popcount function) to get the number of distinct characters!Code Implementation (Pseudocode)