Java Program to Compress String Using Character Count
for (int i = 0; i < s.length(); i++) { count repeats and append char + count }.Examples
How to Think About It
Algorithm
Code
public class StringCompressor { public static String compress(String s) { if (s == null || s.isEmpty()) return ""; StringBuilder result = new StringBuilder(); int count = 1; for (int i = 0; i < s.length(); i++) { if (i + 1 < s.length() && s.charAt(i) == s.charAt(i + 1)) { count++; } else { result.append(s.charAt(i)).append(count); count = 1; } } return result.toString(); } public static void main(String[] args) { System.out.println(compress("aaabbc")); System.out.println(compress("abcd")); System.out.println(compress("")); } }
Dry Run
Let's trace the string "aaabbc" through the code
Start with first character 'a'
count = 1, next char is 'a' same as current, count becomes 2
Second 'a'
next char is 'a' same as current, count becomes 3
Third 'a'
next char is 'b' different, append 'a3' to result, reset count to 1
First 'b'
next char is 'b' same, count becomes 2
Second 'b'
next char is 'c' different, append 'b2' to result, reset count to 1
First 'c'
no next char, append 'c1' to result
| Character | Count | Action | Result So Far |
|---|---|---|---|
| a | 1->2->3 | Next char same, count increment | |
| a | 3 | Next char different, append 'a3' | a3 |
| b | 1->2 | Next char same, count increment | a3 |
| b | 2 | Next char different, append 'b2' | a3b2 |
| c | 1 | No next char, append 'c1' | a3b2c1 |
Why This Works
Step 1: Counting consecutive characters
The code counts how many times each character repeats in a row using a loop and a count variable.
Step 2: Appending character and count
When the next character is different or the string ends, it adds the current character and its count to the result.
Step 3: Using StringBuilder for efficiency
StringBuilder is used to build the result string efficiently instead of creating many new strings.
Alternative Approaches
public class StringCompressor { public static String compressRec(String s) { if (s == null || s.isEmpty()) return ""; return compressHelper(s, 0, 1, new StringBuilder()); } private static String compressHelper(String s, int index, int count, StringBuilder result) { if (index == s.length() - 1) { result.append(s.charAt(index)).append(count); return result.toString(); } if (s.charAt(index) == s.charAt(index + 1)) { return compressHelper(s, index + 1, count + 1, result); } else { result.append(s.charAt(index)).append(count); return compressHelper(s, index + 1, 1, result); } } public static void main(String[] args) { System.out.println(compressRec("aaabbc")); } }
import java.util.stream.*; public class StringCompressor { public static String compressStream(String s) { if (s == null || s.isEmpty()) return ""; StringBuilder result = new StringBuilder(); int[] count = {1}; IntStream.range(0, s.length()).forEach(i -> { if (i + 1 < s.length() && s.charAt(i) == s.charAt(i + 1)) { count[0]++; } else { result.append(s.charAt(i)).append(count[0]); count[0] = 1; } }); return result.toString(); } public static void main(String[] args) { System.out.println(compressStream("aaabbc")); } }
Complexity: O(n) time, O(n) space
Time Complexity
The program loops through the string once, so time grows linearly with input size.
Space Complexity
The output string can be up to twice the input length in worst case (each char followed by count), so space is O(n).
Which Approach is Fastest?
The iterative approach with StringBuilder is fastest and simplest; recursion adds overhead, streams add complexity.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Iterative with StringBuilder | O(n) | O(n) | Simple and efficient for all inputs |
| Recursive | O(n) | O(n) | Elegant but less efficient for large strings |
| Java Streams | O(n) | O(n) | Modern style but less clear and more complex |