Java Programs›Strings›Compress a String

Compress a String in Java

intermediate·  Strings  ·  String

Problem

Run-length encoding stores a run of identical characters as the character plus how many times it repeats, so aaab becomes a3b1.

Given a string, compress it by writing each character followed by the length of its consecutive run.

Input
"aaabccdddd"
Output
"a3b1c2d4"

Java Program

Java
public class CompressString { public static void main(String[] args) { String text = "aaabccdddd"; StringBuilder compressed = new StringBuilder(); int i = 0; while (i < text.length()) { char c = text.charAt(i); int run = 0; while (i < text.length() && text.charAt(i) == c) { // measure the run of this character run++; i++; } compressed.append(c).append(run); } System.out.println("Original: " + text); System.out.println("Compressed: " + compressed); } }

Output

Original: aaabccdddd Compressed: a3b1c2d4

Core Logic

Walking the string once, an inner loop measures how far each run of the same character extends, then records the character and its run length.

How It Works
  1. 1c holds the character that starts the current run.
  2. 2The inner while advances i and increments run for as long as the characters match c.
  3. 3When the run ends, c and run are appended to compressed.
  4. 4The outer loop continues from where the inner loop stopped, so every character is read exactly once.
aaa → a3, b → b1, cc → c2, dddd → d4.
💡

Key Point: Because the inner loop moves i forward, the two nested loops still take one linear pass — nested loops don't automatically mean O(n²).

Complexity
Time Complexity: O(n)Space Complexity: O(n)

Why: Each character is read once, and the compressed output can be up to twice the input length when nothing repeats.

Key Concepts

while looprun countingStringBuilder

Approach 2: Skip Single Counts, Keep the Shorter Result

Java
public class CompressStringShorterOnly { public static void main(String[] args) { System.out.println(compress("aaabccdddd")); System.out.println(compress("abcd")); // compressing would make it longer } static String compress(String text) { StringBuilder out = new StringBuilder(); for (int i = 0; i < text.length(); ) { int start = i; while (i < text.length() && text.charAt(i) == text.charAt(start)) i++; int run = i - start; out.append(text.charAt(start)); if (run > 1) out.append(run); // single characters stay as they are } return out.length() < text.length() ? out.toString() : text; // keep whichever is shorter } }

Output

a3bc2d4 abcd

Core Logic

A practical variant writes counts only for runs longer than one, and falls back to the original text when compression wouldn't actually save space.

How It Works
  1. 1start marks the beginning of a run, and i advances past it.
  2. 2run = i - start gives the run length.
  3. 3The count is appended only when run > 1, so b stays b.
  4. 4The method returns whichever of the compressed and original strings is shorter.
aaabccdddd becomes a3bc2d4 (7 characters instead of 10), while abcd is returned unchanged.
💡

Key Point: Dropping the 1s makes the output ambiguous to decode when the text itself contains digits — fine for display, but not for a reversible format.

Complexity
Time Complexity: O(n)Space Complexity: O(n)

Why: One pass builds the output, and the builder holds at most about n characters.

Key Concepts

helper methodconditional appendlength comparison

Interview Questions

When does run-length encoding make a string longer?

When characters rarely repeat. "abcd" becomes "a1b1c1d1", twice the original length, which is why practical versions keep whichever result is shorter.

How would you decompress the result?

Read a character, then read all the digits that follow it as a count, and append the character that many times. Counts above 9 need several digits, so read until the next non-digit.

Learn the Concept

Related Programs