String Operations & Language APIs
Scope — The language mechanics of strings: Python slicing and methods, Java
StringandStringBuilder, character classification and case conversion, char arithmetic, the split/join traps and the build-performance rules — not the algorithms that use them. See also: string.md — the parent sheet, holding the string pattern catalogue and its templates; string_examples.md — the worked LC solution archive split out of the same file; python_trick.md and java_trick.md — the general language-idiom sheets; Collection.md — choosing among Java’s collections.
LeetCode Problem Lists
Overview
Nothing here is an algorithm. It is the layer underneath: the calls you reach for without
thinking, plus the handful that quietly cost you a submission — split taking a regex in Java,
+= in a loop being quadratic, Counter keeping zero entries, isalpha() being true for
non-ASCII letters.
Key Properties
- Immutability:
Stringis immutable in both Python and Java — every “modification” allocates - Cost model: concatenation is O(len); doing it in a loop is O(n²). Collect into a list /
StringBuilderand join once - Char arithmetic:
ord(c) - ord('a')in Python,c - 'a'in Java, is the standard index into a 26-slot table - When to read this: before an interview, and whenever a “simple” string call behaved unexpectedly
Python String Operations
# String <-> List conversion
s = "abcd"
char_list = list(s) # ['a', 'b', 'c', 'd']
back_to_string = ''.join(char_list) # "abcd"
# Join with separator
words = ["hello", "world"]
sentence = " ".join(words) # "hello world"
csv = ",".join(words) # "hello,world"
# Reverse iteration
s = "abcd"
for i in range(len(s)-1, -1, -1):
print(s[i]) # d, c, b, a
# String slicing
s = "abcdef"
reversed_s = s[::-1] # "fedcba"
every_other = s[::2] # "ace"
substring = s[1:4] # "bcd"
# Common string methods
s = " Hello World "
s.strip() # "Hello World"
s.lower() # " hello world "
s.upper() # " HELLO WORLD "
s.replace("World", "Python") # " Hello Python "
s.split() # ['Hello', 'World']
# Character operations
char = 'a'
ord_val = ord(char) # 97
back_to_char = chr(97) # 'a'
is_alpha = char.isalpha() # True
is_digit = '5'.isdigit() # True
Java String Operations
// String operations in Java
String s = "abcd";
// String to char array
char[] chars = s.toCharArray();
String backToString = new String(chars);
// StringBuilder for mutable strings
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" World");
sb.reverse();
String result = sb.toString();
// String methods
String str = " Hello World ";
str.trim() // "Hello World"
str.toLowerCase() // " hello world "
str.toUpperCase() // " HELLO WORLD "
str.replace("World", "Java") // " Hello Java "
str.substring(2, 7) // "Hello"
String[] words = str.split(" ");
// Character operations
char c = 'a';
int ascii = (int) c; // 97
char backToChar = (char) 97; // 'a'
boolean isLetter = Character.isLetter(c);
boolean isDigit = Character.isDigit('5');
Character Classification & Case
The predicates and case conversions that the two-pointer and parsing templates in string.md lean on.
// java
// Key methods for character checking
char x = 'a';
// Check if alphabetic letter (a-z, A-Z)
Character.isLetter(x); // true
// Check if digit (0-9)
Character.isDigit('5'); // true
// Check if letter or digit
Character.isLetterOrDigit(x); // true
// Check if whitespace
Character.isWhitespace(' '); // true
// Case conversion
Character.toLowerCase('A'); // 'a'
Character.toUpperCase('b'); // 'B'
# python
# Character checking methods
char = 'a'
# Check if alphabetic
char.isalpha() # True
# Check if digit
'5'.isdigit() # True
# Check if alphanumeric
char.isalnum() # True
# Check if whitespace
' '.isspace() # True
# Case conversion
char.upper() # 'A'
char.lower() # 'a'
- ⚠️ Python’s
isalpha()/isdigit()are Unicode-aware:'²'.isdigit()isTrueand'é'.isalpha()isTrue. When a problem says “lowercase English letters”, test with'a' <= c <= 'z'if you need to be exact. - ⚠️ Java’s
Character.isLetteris likewise Unicode-aware;Character.isLetterOrDigitis the one the LC 125 style “skip non-alphanumeric” scans want. - ⚠️ Case folding is not always a round trip —
toLowerCaseon some locales changes length. Interview inputs are ASCII, but say so out loud rather than assuming it.
String Manipulation Tricks
# go through elements in str AVOID index out of range error
x = '1234'
for i in range(len(x)):
if i == len(x)-1 or x[i] != x[i+1]:
print (x[i])
# string -> array
a = 1234
a_array = list(str(a))
In [12]: a_array
Out[12]: ['1', '2', '3', '4']
// java
// split string (java)
/** NOTE !!! split string via .split("") */
for (String x : s.split("")){
System.out.println(x);
}
String Building Performance
# Python: Use list and join
result = []
for item in items:
result.append(process(item))
return ''.join(result)
// Java: Use StringBuilder
StringBuilder sb = new StringBuilder();
for (String item : items) {
sb.append(process(item));
}
return sb.toString();
- ⚠️
s += xinside a loop is O(n²) in both languages. CPython sometimes optimises the refcount-1 case, but never rely on it. - ⚠️
StringBuilderis not thread-safe (that isStringBuffer) — irrelevant in interviews, worth knowing as a follow-up answer. - ⚠️ Pre-size when you know the answer’s length:
new StringBuilder(n)avoids the doubling copies.
Summary & Quick Reference
| Task | Python | Java |
|---|---|---|
| String → chars | list(s) |
s.toCharArray() |
| Chars → string | "".join(chars) |
new String(chars) |
| Reverse | s[::-1] |
new StringBuilder(s).reverse().toString() |
| Substring | s[i:j] |
s.substring(i, j) |
| Every other char | s[::2] |
manual loop with i += 2 |
| Split on whitespace | s.split() |
s.trim().split("\\s+") |
| Split on a literal dot | s.split(".") |
s.split("\\.") — the argument is a regex |
| Split keeping empty tails | s.split(",") |
s.split(",", -1) |
| Join with separator | ",".join(parts) |
String.join(",", parts) |
| Strip whitespace | s.strip() |
s.trim() / s.strip() (Java 11+) |
| Case fold | s.lower() / s.upper() |
s.toLowerCase() / s.toUpperCase() |
| Replace | s.replace(a, b) |
s.replace(a, b) |
| Find substring | s.find(p) (-1 if absent) |
s.indexOf(p) (-1 if absent) |
| Char → code / code → char | ord(c) / chr(n) |
(int) c / (char) n |
| Index into the 26 letters | ord(c) - ord('a') |
c - 'a' |
| Is letter / digit / alnum | c.isalpha() / c.isdigit() / c.isalnum() |
Character.isLetter(c) / isDigit(c) / isLetterOrDigit(c) |
| Frequency table | Counter(s) |
int[26] or HashMap<Character,Integer> |
| Build incrementally | list append then join |
StringBuilder.append then toString |
Gotchas worth memorising
- Java
splitis regex-based."a.b".split(".")returns an array of empty strings. - Java
splitdrops trailing empties."a,,".split(",")has length 1; pass-1to keep them. - Python slicing never throws.
s[5:99]on a 3-char string is"", not an error — convenient, and a silent-bug source. Counterkeeps zeros. After decrementing to0,delthe key or the==comparison against a freshCounterfails.- Never concatenate in a loop. Collect and join.