-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented Java
-
Section 4: Collections Framework
-
Section 5: Exception Handling
-
Section 6: Generics
-
Section 7: Functional Java
-
Section 8: Concurrency
-
Section 9: I/O and NIO
-
Section 10: JVM Internals
-
Section 11: Modern Java Features
-
Section 12: Build Tools and Project Structure
-
Section 13: Testing
-
Section 14: Databases and Persistence
-
Section 15: Networking
-
Section 16: Design and Best Practices
-
Section 17: Reflection and Annotations
-
Section 18: Logging and Diagnostics
-
Section 19: Date, Time, and Internationalization
-
Section 20: Java Platform Module System
-
Section 21: Security in Java
-
Section 22: Advanced Collections and Data Structures
-
Section 23: More Concurrency Patterns
-
Section 24: Compression, Files, and System Integration
-
Section 25: GUI Programming
-
Section 26: Practical Projects
-
Section 27: Data Structures and Algorithms
-
Section 28: Interview and Algorithm Practice
-
Section 29: JSON and Data Interchange
-
Section 30: More Concurrency Utilities
-
Section 31: More Collections and Streams Practice
-
Section 32: More File and System Programming
-
Section 33: Standard Library Deep Dive
-
Section 34: More Practice and Drills
-
Section 35: More Testing and Quality
-
Section 36: More Design Patterns and Architecture
-
Section 37: Career and Ecosystem
-
Section 38: More OOP and Architecture Practice
-
Section 39: More Enterprise Concepts
-
Section 40: Advanced JavaFX
-
Section 41: More Interview Practice
316: Solving Common String Manipulation Interview Problems
When you're sitting in a high-pressure interview, your brain naturally gravitates toward the shortest path to a working solution. In Java, when we deal with strings, that path usually involves the + operator. It's intuitive, it's fast to type, and for a small test case, it works perfectly. But in a professional setting—and certainly in an interview with a senior engineer—that approach is a red flag. It tells the interviewer that you might not understand how Java handles memory under the hood.
Let's look at a classic problem: reversing the words in a sentence. If I give you "The quick brown fox", I want "fox brown quick The" back. A lot of candidates will jump straight to splitting the string and looping backward, concatenating the results into a new string.
The Hidden Cost of the Plus Sign
// The "Naive" way - avoid this in interviews
public String reverseWordsNaive(String s) {
String[] words = s.split(" ");
String result = "";
for (int i = words.length - 1; i >= 0; i--) {
result += words[i] + " ";
}
return result.trim();
}
On the surface, this is logically sound. But here is the problem: Strings in Java are immutable. Every single time you use result += words[i], Java isn't just appending text to an existing object. It's creating a brand new String object, copying the entire content of the old result into it, and then adding the new word. If you have a sentence with 1,000 words, you aren't doing 1,000 operations; you're doing an astronomical amount of copying. Your time complexity effectively jumps from O(n) to O(n²). It's a classic performance trap.
Why StringBuilder Saves Your Runtime
To fix this, you need to use StringBuilder. Think of it as a mutable buffer. Instead of creating a new object every time you want to add a character, StringBuilder modifies an internal array. When that array fills up, it grows, but it does so in a way that keeps the average cost of adding a character—the amortized time—at O(1).
// The professional way
public String reverseWordsBetter(String s) {
String[] words = s.split("\\s+"); // Note the regex change here
StringBuilder sb = new StringBuilder();
for (int i = words.length - 1; i >= 0; i--) {
sb.append(words[i]);
if (i > 0) {
sb.append(" ");
}
}
return sb.toString();
}
I shifted the logic slightly here. Instead of calling trim() at the end, which creates yet another string object, I'm just checking if I'm at the last word before adding a space. It's a small detail, but it shows you're thinking about object allocation.
Handling the 'Dirty' Input Problem
There is one more trap in the example above that catches people: split(" "). In a real-world interview, the interviewer will almost certainly throw a string at you with multiple spaces, leading or trailing whitespace, or even tabs. If you use split(" ") on " Hello World ", you'll end up with a bunch of empty strings in your array, and your output will be a mess of unnecessary gaps.
I used split("\\s+") in the second example. The \\s+ is a regular expression that means "one or more whitespace characters." This effectively collapses all consecutive spaces into a single delimiter. Pairing this with a trim() on the input string before splitting is usually the gold standard for these types of problems. It ensures your logic only processes the actual words, not the noise around them.
📋 Practical Task
Build a Robust Sentence Reverser with Whitespace Normalization
Your task is to implement a method public String cleanAndReverse(String input). The method must take a string that potentially contains irregular spacing (leading, trailing, and multiple spaces between words) and return the words in reverse order, separated by exactly one single space.
- Requirement 1: You must use
StringBuilderto construct the final result to ensure O(n) time complexity. - Requirement 2: You must use a regular expression in your
split()call to handle multiple whitespace characters. - Requirement 3: The final output must not have leading or trailing spaces.
Test Case:
Input: " The quick brown fox "
Expected Output: "fox brown quick The"
There are no comments for now.