Category: Easy | Concepts used: String buffer filtering, character comparison, String immutability
Problem Statement
Given a string and a target character, remove every occurrence of that character.
Input : str = "banana", ch = 'a' Output: "bnn"
Input : str = "hello", ch = 'z' Output: "hello" (unchanged)
Examples (with edge scenarios)
| # | str | ch | Output | Why |
|---|---|---|---|---|
| 1 | "banana" | 'a' | "bnn" | All 3 'a's are removed |
| 2 | "hello" | 'z' | "hello" | 'z' is not present |
| 3 | "" | 'x' | "" | Empty string yields empty output |
| 4 | "aaaa" | 'a' | "" | All characters match target, leaving empty |
| 5 | "Banana" | 'a' | "Bnn" | Case-sensitive mismatch (only 'a' is removed, 'B' remains) |
⚠️ Common Beginner Mistake
Mistake Impact Fix Replacing with a space ( ch = ' ') instead of empty spaceLeaves empty character gaps in the middle of words Accumulate only matching indices to shrink the string Using replaceAllon literal characters without escapingCharacters like .or*are parsed as regex controls, corrupting the resultUse replace(String.valueOf(ch), "")for safe literal swaps
Before You Code: Clarify the Contract
Before choosing an algorithm, confirm how null and empty strings should behave, whether comparison is case-sensitive, and whether spaces or punctuation count. Java char values are UTF-16 code units, not always complete human-visible Unicode characters, so international text may require code points or grapheme-aware libraries.
Analogy: Conveyor Belt Quality Inspector
Imagine you are an inspector at a manufacturing line:
- You are looking at a conveyor belt of items (the string).
- You are instructed: “Remove all cracked cups (the target character) from the line.”
- You inspect each item:
- If it is a cracked cup, you discard it (skip it).
- If it is any other clean item, you place it on the shipping tray (
result.append(ch)).
- The shipping tray ends up containing only clean, uncracked items!
Solution 1 — Loop + StringBuilder (Optimal Manual)
This is the standard manual approach using a mutable string buffer.
Intuition
We traverse the string, comparing each character to the target. We append to our StringBuilder only when the character does not match, avoiding intermediate string copy operations.
public class RemoveCharOccurrences {
public static String removeChar(String str, char target) {
if (str == null || str.isEmpty()) {
return str;
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch != target) { // Only append if it is not the target
result.append(ch);
}
}
return result.toString();
}
public static void main(String[] args) {
System.out.println(removeChar("banana", 'a')); // "bnn"
System.out.println(removeChar("hello", 'z')); // "hello"
System.out.println(removeChar("aaaa", 'a')); // ""
System.out.println(removeChar("", 'x')); // ""
}
}
Output:
bnn
hello
Solution 2 — Using String.replace() (Concise & Literal)
This is the preferred built-in helper method.
Intuition
While Java doesn’t have a direct character-based removal method, we can convert the target character into a single-character string using String.valueOf() and call str.replace(). In Java, replace() replaces all literal matches without regular expression compilation.
public class RemoveCharReplace {
public static String removeChar(String str, char target) {
if (str == null || str.isEmpty()) {
return str;
}
// String.valueOf(target) converts the char to a String sequence
return str.replace(String.valueOf(target), "");
}
public static void main(String[] args) {
System.out.println(removeChar("banana", 'a')); // "bnn"
}
}
Output:
bnn
📊 Visual Flowchart
graph TD
Start["Input String S, target char T"] --> NullCheck{"S is null?"}
NullCheck -->|Yes| RetNull["Return Null"]
NullCheck -->|No| InitBuilder["Initialize StringBuilder sb"]
InitBuilder --> Loop{"i < S.length()?"}
Loop -->|Yes| Fetch["ch = S.charAt(i)"]
Fetch --> CheckTarget{"ch == T?"}
CheckTarget -->|Yes| Skip["i++"]
CheckTarget -->|No| Append["sb.append(ch)"]
Append --> Skip
Skip --> Loop
Loop -->|No| Convert["sb.toString()"]
Convert --> End["Return result"]
Interviewer Insights
This question tests basic flow control, heap memory limits, and API scope.
Follow-up questions you might get:
- “What is the difference between String.replace() and String.replaceAll()?” →
replace()performs literal string replacements. It converts inputs into CharSequences and scans characters.replaceAll()treats the input target as a regular expression.- Interview Tip: Proactively state that using
replaceAllto remove a single character like.without escaping it (str.replaceAll(".", "")) will empty the entire string, since.matches any character in regex.replace(".", "")is safe.
- “How would you count how many characters were removed?” → Subtract the lengths:
str.length() - result.length().
Quick Recap
| Approach | Time Complexity | Auxiliary Space Complexity | Regex Overhead? | Interview Signal |
|---|---|---|---|---|
StringBuilder Loop | (O(N)) | (O(N)) | No | Standard loop construction, memory-conscious |
replace(charString, "") | (O(N)) | (O(N)) | No | Concise literal replacement, clean API usage |
replaceAll(regex, "") | (O(N)) | (O(N)) | Yes | Overkill for simple characters, prone to regex special-char bugs |
- Author
- TechByteByByte Editorial Team
- Reviewed by
- TechByteByByte Admin
- Published
- Last reviewed