3003. Maximize the Number of Partitions After Operations
UnknownView on LeetCode
Time: O(n * 2^26)
Space: O(n * 2^26)
Problem Overview
Maximize the Number of Partitions After Operations (Unknown) asks you to solve a structured algorithmic task. This is a common Dynamic Programming / String pattern in coding interviews. Bitmask DP tracking (position, active-char-mask, canChange) to maximize partitions.
A full step-by-step explanation is being added. See the study guide for pattern-based practice.
Approach
Bitmask DP tracking (position, active-char-mask, canChange) to maximize partitions.
Related patterns: Dynamic Programming, String, Bit Manipulation
3003.cs
C#
// Approach: Bitmask DP tracking (position, active-char-mask, canChange) to maximize partitions.
// Time: O(n * 2^26) Space: O(n * 2^26)
public class Solution
{
// Memoization dictionary: key is Tuple<int, int, int> representing (position, bitmask, canChange)
private Dictionary<(int, int, int), int> memo = new Dictionary<(int, int, int), int>();
private string inputString;
private int maxDistinctChars;
public int MaxPartitionsAfterOperations(string s, int k)
{
this.inputString = s;
this.maxDistinctChars = k;
// Start DFS from position 0, empty bitmask, with 1 change allowed
return Dfs(0, 0, 1);
}
/// <summary>
/// Dynamic programming with memoization to find maximum partitions
/// </summary>
/// <param name="index">current position in string</param>
/// <param name="currentMask">bitmask representing distinct characters in current partition</param>
/// <param name="canChange">flag indicating if we can still change a character (1 = yes, 0 = no)</param>
/// <returns>maximum number of partitions from current state</returns>
private int Dfs(int index, int currentMask, int canChange)
{
// Base case: reached end of string
if (index >= inputString.Length)
return 1;
var memoKey = (index, currentMask, canChange);
if (memo.TryGetValue(memoKey, out int cachedResult))
return cachedResult;
int charBit = 1 << (inputString[index] - 'a');
int newMask = currentMask | charBit;
int maxPartitions;
if (CountBits(newMask) > maxDistinctChars)
// Adding current char exceeds k distinct chars, start new partition
maxPartitions = Dfs(index + 1, charBit, canChange) + 1;
else
// Continue with current partition
maxPartitions = Dfs(index + 1, newMask, canChange);
// Try changing current character (if we haven't used our change yet)
if (canChange > 0)
{
for (int charIndex = 0; charIndex < 26; ++charIndex)
{
newMask = currentMask | (1 << charIndex);
if (CountBits(newMask) > maxDistinctChars)
maxPartitions = Math.Max(maxPartitions, Dfs(index + 1, 1 << charIndex, 0) + 1);
else
maxPartitions = Math.Max(maxPartitions, Dfs(index + 1, newMask, 0));
}
}
memo[memoKey] = maxPartitions;
return maxPartitions;
}
// Helper method to count set bits in an integer
private int CountBits(int n)
{
int count = 0;
while (n != 0)
{
count += n & 1;
n >>= 1;
}
return count;
}
}Was this solution helpful?
Related Problems
- 12. Integer to Roman(Medium)
- 13. Roman to Integer(Easy)
- 14. Longest Common Prefix(Easy)
- 22. Generate Parentheses(Medium)
- 29. Divide Two Integers(Medium)
- 30. Substring with Concatenation of All Words(Hard)