Splitting a string into maximum parts in JavaScript

In JavaScript, partitioning a string into maximum parts means dividing it so that each letter appears in only one partition. This creates the maximum number of non-overlapping sections possible.

Problem Statement

We need to write a JavaScript function that takes a string and partitions it into as many parts as possible, where each letter appears in at most one part. The function returns an array of integers representing the size of these parts.

Input Example:

const str = "ababcbacadefegdehijhklij";

Expected Output:

[9, 7, 8]

Explanation: The partitions are "ababcbaca" (9 chars), "defegde" (7 chars), and "hijhklij" (8 chars). Each letter appears in only one partition.

Algorithm Approach

The solution uses a two-pass approach:

  1. First pass: Record the last occurrence index of each character
  2. Second pass: Expand partition boundaries based on character positions

Implementation

const str = "ababcbacadefegdehijhklij";

const splitStrings = (str = '') => {
    const res = [];
    const map = {};
    
    // First pass: record last occurrence of each character
    for (let i = 0; i < str.length; i++) {
        map[str[i]] = i;
    }
    
    let start = 0;
    while (start <= str.length - 1) {
        let end = map[str[start]];
        
        // Expand partition boundary if needed
        for (let i = start + 1; i < end; i++) {
            const currentEnd = map[str[i]];
            if (currentEnd > end) {
                end = currentEnd;
            }
        }
        
        res.push(end - start + 1);
        start = end + 1;
    }
    
    return res;
};

console.log(splitStrings(str));
[ 9, 7, 8 ]

How It Works

The algorithm works by:

  1. Mapping last positions: Store the last occurrence index of each character
  2. Expanding boundaries: For each partition, extend the end boundary whenever we encounter a character that appears later
  3. Creating partitions: Once we reach the end boundary, we've found a complete partition

Step-by-Step Example

const demonstratePartitioning = (str) => {
    const map = {};
    
    // Build last occurrence map
    for (let i = 0; i < str.length; i++) {
        map[str[i]] = i;
    }
    
    console.log("Last occurrence map:", map);
    
    let start = 0;
    let partitionNumber = 1;
    
    while (start <= str.length - 1) {
        let end = map[str[start]];
        console.log(`Partition ${partitionNumber}: starts at ${start}, initial end at ${end}`);
        
        for (let i = start + 1; i < end; i++) {
            const currentEnd = map[str[i]];
            if (currentEnd > end) {
                console.log(`  Extended end from ${end} to ${currentEnd} due to '${str[i]}'`);
                end = currentEnd;
            }
        }
        
        const partition = str.substring(start, end + 1);
        console.log(`  Final partition: "${partition}" (length: ${end - start + 1})`);
        
        start = end + 1;
        partitionNumber++;
    }
};

demonstratePartitioning("ababcbacadefegdehijhklij");
Last occurrence map: { a: 8, b: 5, c: 7, d: 14, e: 15, f: 11, g: 13, h: 19, i: 22, j: 23, k: 20, l: 21 }
Partition 1: starts at 0, initial end at 8
  Extended end from 8 to 5 due to 'b'
  Extended end from 5 to 8 due to 'a'
  Final partition: "ababcbaca" (length: 9)
Partition 2: starts at 9, initial end at 14
  Extended end from 14 to 15 due to 'e'
  Final partition: "defegde" (length: 7)
Partition 3: starts at 16, initial end at 19
  Extended end from 19 to 22 due to 'i'
  Extended end from 22 to 23 due to 'j'
  Extended end from 23 to 20 due to 'h'
  Extended end from 20 to 21 due to 'k'
  Extended end from 21 to 22 due to 'l'
  Extended end from 22 to 23 due to 'i'
  Extended end from 23 to 23 due to 'j'
  Final partition: "hijhklij" (length: 8)

Time and Space Complexity

Time Complexity: O(n²) in the worst case, where n is the string length. The outer while loop runs at most n times, and the inner for loop can run up to n times per iteration.

Space Complexity: O(1) for the character map (at most 26 lowercase letters) plus O(k) for the result array, where k is the number of partitions.

Conclusion

This greedy algorithm efficiently partitions a string into maximum parts by tracking character boundaries. The key insight is extending partition boundaries whenever we encounter characters that appear later in the string.

Updated on: 2026-03-15T23:19:00+05:30

371 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements