
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Lengths of Maximized Partitions of a String
In this article, we will explore the problem of finding the lengths of maximized partitions of a string with unique characters. We will first understand the problem statement and then investigate both the naive and efficient approaches to solve this problem, along with their respective algorithms and time complexities. Lastly, we will implement the solution.
Problem Statement
Given a string, partition the string into as many substrings as possible such that each character of the string appears in only one substring. Return the lengths of these maximized partitions.
Naive Approach
The naive approach is to iterate through the string, recording the last occurrence of each character. Then, iterate through the string again and create partitions whenever the current character's last occurrence is found.
Algorithm (Naive)
Initialize an array to store the last occurrence of each character in the string.
Iterate through the string and record the last occurrence of each character.
Initialize a vector to store the lengths of the partitions.
Iterate through the string again and create partitions whenever the current character's last occurrence is found.
Code (Naive)
Example
Following are the programs to the above algorithm
#include <stdio.h> #include <stdlib.h> #include <string.h> int* partitionLengths(char* s, int* returnSize) { // Allocate memory for storing the last occurrence index of each character int* lastOccurrence = (int*)malloc(26 * sizeof(int)); for (int i = 0; i < 26; i++) { lastOccurrence[i] = -1; // Initialize to -1, indicating character not encountered yet } int len = strlen(s); for (int i = 0; i < len; i++) { lastOccurrence[s[i] - 'a'] = i; // Update last occurrence index of character } // Allocate memory for storing partition lengths int* partitionLengths = (int*)malloc(len * sizeof(int)); int start = 0, end = 0, partitionCount = 0; for (int i = 0; i < len; i++) { // Update end with maximum of its current value and the last occurrence index of current character end = (end > lastOccurrence[s[i] - 'a']) ? end : lastOccurrence[s[i] - 'a']; if (i == end) { // A partition has ended, calculate its length and store it partitionLengths[partitionCount++] = end - start + 1; start = i + 1; // Move the start of the next partition } } *returnSize = partitionCount; // Set the size of the result array return partitionLengths; // Return the array of partition lengths } int main() { char s[] = "abacdc"; int length; int* lengths = partitionLengths(s, &length); printf("Lengths of maximized partitions: "); for (int i = 0; i < length; i++) { printf("%d ", lengths[i]); } free(lengths); return 0; }
Output
Lengths of maximized partitions: 3 3
#include <iostream> #include <vector> #include <string> #include <algorithm> std::vector<int> partitionLengths(std::string s) { std::vector<int> lastOccurrence(26, -1); for (size_t i = 0; i < s.size(); i++) { lastOccurrence[s[i] - 'a'] = i; } std::vector<int> partitionLengths; int start = 0, end = 0; for (size_t i = 0; i < s.size(); i++) { end = std::max(end, lastOccurrence[s[i] - 'a']); if (i == end) { partitionLengths.push_back(end - start + 1); start = i + 1; } } return partitionLengths; } int main() { std::string s = "abacdc"; std::vector<int> lengths = partitionLengths(s); std::cout << "Lengths of maximized partitions: "; for (int length : lengths) { std::cout << length << " "; } return 0; }
Output
Lengths of maximized partitions: 3 3
import java.util.ArrayList; import java.util.List; public class Main { public static List<Integer> partitionLengths(String s) { int[] lastOccurrence = new int[26]; for (int i = 0; i < 26; i++) { lastOccurrence[i] = -1; // Initialize to -1, indicating character not encountered yet } for (int i = 0; i < s.length(); i++) { lastOccurrence[s.charAt(i) - 'a'] = i; // Update last occurrence index of character } List<Integer> partitionLengths = new ArrayList<>(); // List to store partition lengths int start = 0, end = 0; for (int i = 0; i < s.length(); i++) { // Update end with maximum of its current value and the last occurrence index of current character end = Math.max(end, lastOccurrence[s.charAt(i) - 'a']); if (i == end) { // A partition has ended, calculate its length and store it partitionLengths.add(end - start + 1); start = i + 1; // Move the start of the next partition } } return partitionLengths; } public static void main(String[] args) { String s = "abacdc"; List<Integer> lengths = partitionLengths(s); System.out.print("Lengths of maximized partitions: "); for (int length : lengths) { System.out.print(length + " "); } } }
Output
Lengths of maximized partitions: 3 3
def partition_lengths(s): # Initialize a list to store the last occurrence index of each character last_occurrence = [-1] * 26 # Update the last occurrence index of each character for i in range(len(s)): last_occurrence[ord(s[i]) - ord('a')] = i partition_lengths = [] # List to store partition lengths start = end = 0 for i in range(len(s)): # Update end with maximum of its current value and the last occurrence index of current character end = max(end, last_occurrence[ord(s[i]) - ord('a')]) if i == end: # A partition has ended, calculate its length and store it partition_lengths.append(end - start + 1) start = i + 1 # Move the start of the next partition return partition_lengths def main(): s = "abacdc" lengths = partition_lengths(s) print("Lengths of maximized partitions:", end=" ") for length in lengths: print(length, end=" ") if __name__ == "__main__": main()
Output
Lengths of maximized partitions: 3 3
Time Complexity (Naive) ? O(n), where n is the length of the string.
Efficient Approach
The efficient approach is similar to the naive approach, but instead of iterating through the string twice, we can create partitions while recording the last occurrence of each character in a single iteration.
Algorithm (Efficient)
Initialize an array to store the last occurrence of each character in the string.
Initialize a vector to store the lengths of the partitions.
Iterate through the string, record the last occurrence of each character, and create partitions whenever the current character's last occurrence is found.
Code (Efficient)
Example
Following are the programs to the above algorithm
#include <stdio.h> #include <stdlib.h> #include <string.h> int* partitionLengths(char* s, int* returnSize) { // Create an array to store the last occurrence index of each character int lastOccurrence[26]; for (int i = 0; i < 26; i++) { lastOccurrence[i] = -1; // Initialize to -1 indicating character not encountered yet } int len = strlen(s); for (int i = 0; i < len; i++) { lastOccurrence[s[i] - 'a'] = i; // Update last occurrence index of character } // Allocate memory for storing partition lengths int* partitionLengths = (int*)malloc(len * sizeof(int)); int start = 0, end = 0, partitionCount = 0; for (int i = 0; i < len; i++) { // Update end with maximum of its current value and the last occurrence index of current character end = (end > lastOccurrence[s[i] - 'a']) ? end : lastOccurrence[s[i] - 'a']; if (i == end) { // A partition has ended, calculate its length and store it partitionLengths[partitionCount++] = end - start + 1; start = i + 1; // Move the start of the next partition } } *returnSize = partitionCount; // Set the size of the result array return partitionLengths; // Return the array of partition lengths } int main() { char s[] = "abacdc"; int length; int* lengths = partitionLengths(s, &length); printf("Lengths of maximized partitions: "); for (int i = 0; i < length; i++) { printf("%d ", lengths[i]); // Print the lengths of maximized partitions } free(lengths); return 0; }
Output
Lengths of maximized partitions: 3 3
#include <iostream> #include <vector> #include <string> #include <algorithm> std::vector<int> partitionLengths(std::string s) { std::vector<int> lastOccurrence(26, -1); std::vector<int> partitionLengths; int start = 0, end = 0; for (size_t i = 0; i < s.size(); i++) { lastOccurrence[s[i] - 'a'] = i; } for (size_t i = 0; i < s.size(); i++) { end = std::max(end, lastOccurrence[s[i] - 'a']); if (i == end) { partitionLengths.push_back(end - start + 1); start = i + 1; } } return partitionLengths; } int main() { std::string s = "abacdc"; std::vector<int> lengths = partitionLengths(s); std::cout << "Lengths of maximized partitions: "; for (int length : lengths) { std::cout << length << " "; } return 0; }
Output
Lengths of maximized partitions: 3 3
import java.util.ArrayList; import java.util.List; public class Main { public static List<Integer> partitionLengths(String s) { // Create an array to store the last occurrence index of each character int[] lastOccurrence = new int[26]; for (int i = 0; i < 26; i++) { lastOccurrence[i] = -1; // Initialize to -1 indicating character not encountered yet } List<Integer> partitionLengths = new ArrayList<>(); // List to store partition lengths int start = 0, end = 0; // Update the last occurrence index of each character for (int i = 0; i < s.length(); i++) { lastOccurrence[s.charAt(i) - 'a'] = i; } for (int i = 0; i < s.length(); i++) { // Update end with maximum of its current value and the last occurrence index of current character end = Math.max(end, lastOccurrence[s.charAt(i) - 'a']); if (i == end) { // A partition has ended, calculate its length and store it partitionLengths.add(end - start + 1); start = i + 1; // Move the start of the next partition } } return partitionLengths; } public static void main(String[] args) { String s = "abacdc"; List<Integer> lengths = partitionLengths(s); System.out.print("Lengths of maximized partitions: "); for (int length : lengths) { System.out.print(length + " "); // Print the lengths of maximized partitions } } }
Output
Lengths of maximized partitions: 3 3
def partition_lengths(s): # Initialize a list to store the last occurrence index of each character last_occurrence = [-1] * 26 partition_lengths = [] # List to store partition lengths start = end = 0 # Update the last occurrence index of each character for i in range(len(s)): last_occurrence[ord(s[i]) - ord('a')] = i for i in range(len(s)): # Update end with maximum of its current value and the last occurrence index of current character end = max(end, last_occurrence[ord(s[i]) - ord('a')]) if i == end: # A partition has ended, calculate its length and store it partition_lengths.append(end - start + 1) start = i + 1 # Move the start of the next partition return partition_lengths def main(): s = "abacdc" lengths = partition_lengths(s) print("Lengths of maximized partitions:", end=" ") for length in lengths: print(length, end=" ") # Print the lengths of maximized partitions if __name__ == "__main__": main()
Output
Lengths of maximized partitions: 3 3
Time Complexity (Efficient) ? O(n), where n is the length of the string.
Conclusion
In this article, we explored the problem of finding the lengths of maximized partitions of a string with unique characters. We discussed both the naive and efficient approaches to solve this problem, along with their algorithms and time complexities. The efficient approach, which combines recording the last occurrence of each character and creating partitions in a single iteration, provides an optimized solution. Both approaches have the same time complexity, but the efficient approach uses fewer iterations.