Reverse a String in C, C++, Java and Python
String reversal in C, C++, Java and Python: in-place two-pointer swap, std::reverse, StringBuilder.reverse, and Python slice notation, with complexity analysis.
Reversing a string is a first-round coding question at Infosys, Wipro, and TCS, and it appears in AMCAT Automata-Fix rounds during the early placement season.
The sections below cover all four languages with two approaches each: in-place swap and copy-based, or the standard library equivalent and the manual alternative. Each section includes a trace through the input “faceprep” and a complexity note so you can answer follow-up questions about memory usage.
Understanding String Reversal
A reversed string has its characters in the opposite order. Input “faceprep” becomes “perpecaf”. Input “welcome” becomes “emoclew”.
Two strategies cover all implementations:
- In-place: swap characters from both ends, walking inward with two pointers. No extra buffer. This works on mutable char arrays (C, C++ raw arrays) and on Java char arrays after converting from a String.
- Copy-based: build a new string by reading the original from the last character to the first. Required for immutable types — Java’s
Stringand Python’sstrcannot be modified in-place.
String reversal connects directly to palindrome checking: a string is a palindrome if and only if it equals its own reverse. Understanding reversal makes the palindrome check a one-step comparison.
Reverse a String in C
Approach 1: In-Place Two-Pointer Swap
C strings are null-terminated char arrays, so in-place modification is straightforward. Two indices start at opposite ends and walk inward, swapping one pair of characters at each step.
#include <stdio.h>
#include <string.h>
void reverseString(char *s) {
int left = 0, right = (int)strlen(s) - 1;
while (left < right) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
int main() {
char str[] = "faceprep";
reverseString(str);
printf("%s\n", str); /* perpecaf */
return 0;
}
Trace Through “faceprep” (length 8, indices 0–7)
- Step 1:
left=0 (‘f’),right=7 (‘p’). Swap. String: “pacerp ef” becomes p-a-c-e-p-r-e-f. - Step 2:
left=1 (‘a’),right=6 (‘e’). Swap. String: p-e-c-e-p-r-a-f. - Step 3:
left=2 (‘c’),right=5 (‘r’). Swap. String: p-e-r-e-p-c-a-f. - Step 4:
left=3 (‘e’),right=4 (‘p’). Swap. String: p-e-r-p-e-c-a-f. - Step 5:
left=4,right=3. Conditionleft < rightis false. Loop ends. - Result: “perpecaf” ✓
Approach 2: Copy to New Buffer
When the original string must remain unchanged, write characters from the end into a freshly allocated buffer.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *reverseStringCopy(const char *s) {
int n = (int)strlen(s);
char *rev = (char *)malloc(n + 1);
for (int i = 0; i < n; i++) {
rev[i] = s[n - 1 - i];
}
rev[n] = '\0';
return rev;
}
int main() {
const char *original = "faceprep";
char *reversed = reverseStringCopy(original);
printf("%s\n", reversed); /* perpecaf */
free(reversed);
return 0;
}
Complexity
- In-place: O(n) time, O(1) space. Exactly n/2 swaps, two index variables.
- Copy-based: O(n) time, O(n) space. One
mallocof size n+1.
The in-place version is the expected answer when an interviewer asks for the approach “without extra memory.”
Reverse a String in C++
Approach 1: std::reverse
std::reverse from <algorithm> reverses any bidirectional iterator range in-place. For std::string, pass s.begin() and s.end():
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main() {
string s = "faceprep";
reverse(s.begin(), s.end());
cout << s << "\n"; // perpecaf
return 0;
}
std::reverse performs the two-pointer swap internally, holding only two iterators and a temporary. It runs in O(n) time and O(1) space.
Approach 2: Manual Two-Pointer Swap
Some interviewers ask for the explicit swap logic as a follow-up to the STL one-liner:
#include <iostream>
#include <string>
using namespace std;
string reverseManual(string s) {
int left = 0, right = (int)s.size() - 1;
while (left < right) {
swap(s[left], s[right]);
left++;
right--;
}
return s;
}
int main() {
cout << reverseManual("faceprep") << "\n"; // perpecaf
return 0;
}
Trace Through “faceprep”
Same swap sequence as the C trace: four swaps at index pairs (0,7), (1,6), (2,5), (3,4), then the loop exits with result “perpecaf”. The only difference from C is that std::string manages its own memory, so no malloc or free is needed.
Complexity
- std::reverse: O(n) time, O(1) space (in-place).
- Manual swap on a value parameter: O(n) time, O(n) space because the string is copied on function entry. Passing by reference or operating on the string directly drops that to O(1) space.
Reverse a String in Java
Java’s String type is immutable. Neither approach below modifies the original; both produce a new object.
Approach 1: StringBuilder.reverse()
StringBuilder is a mutable character sequence. Its reverse() method swaps characters in-place inside the internal buffer; toString() then produces a new immutable String.
public class ReverseString {
public static String reverse(String s) {
return new StringBuilder(s).reverse().toString();
}
public static void main(String[] args) {
System.out.println(reverse("faceprep")); // perpecaf
System.out.println(reverse("welcome")); // emoclew
}
}
One note on comparisons: use .equals() to compare String values, not ==. Java’s == compares object references. Two separate String objects containing “perpecaf” will pass .equals() but may fail ==.
Approach 2: Char Array Swap
Convert to a char array with toCharArray(), apply the two-pointer swap directly, then construct a new String from the modified array:
public class ReverseString {
public static String reverseCharArray(String s) {
char[] arr = s.toCharArray();
int left = 0, right = arr.length - 1;
while (left < right) {
char temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
return new String(arr);
}
public static void main(String[] args) {
System.out.println(reverseCharArray("faceprep")); // perpecaf
}
}
Trace Through “faceprep”
toCharArray() produces ['f','a','c','e','p','r','e','p']. The four swaps at index pairs (0,7), (1,6), (2,5), (3,4) yield ['p','e','r','p','e','c','a','f'], and new String(arr) produces “perpecaf” ✓.
Complexity
- StringBuilder.reverse(): O(n) time, O(n) space. The
StringBuilderholds a copy of all n characters. - Char array swap: O(n) time, O(n) space.
toCharArray()allocates a copy;new String(arr)allocates another.
Both approaches allocate O(n) extra space. Java strings are immutable, so there is no O(1)-space path here.
Reverse a String in Python
Python strings are immutable. Both approaches return a new string object.
Approach 1: Slice Notation
s[::-1] uses extended slice syntax: start omitted (defaults to end of string), stop omitted (defaults to beginning), step -1 (walk backwards one character at a time):
s = "faceprep"
reversed_s = s[::-1]
print(reversed_s) # perpecaf
One expression. No function call. This is the idiomatic Python form and the answer most interviewers expect.
Approach 2: reversed() and join
The built-in reversed() returns an iterator over the characters in reverse order. Passing it to "".join() produces the reversed string:
s = "faceprep"
reversed_s = "".join(reversed(s))
print(reversed_s) # perpecaf
Both produce identical output. s[::-1] is more compact; reversed() with join makes the two-step process (iterate backwards, then concatenate) explicit.
Trace Through “faceprep”
s[::-1] steps from index 7 (‘p’) down to index 0 (‘f’), collecting characters in order: p, e, r, p, e, c, a, f. Result: “perpecaf” ✓.
Complexity
- s[::-1]: O(n) time, O(n) space. A new string object is created.
- reversed() + join: O(n) time, O(n) space. The iterator traversal is O(n); the join allocates a new string of length n.
Complexity Summary
| Language | Approach | Time | Space |
|---|---|---|---|
| C | Two-pointer swap (in-place) | O(n) | O(1) |
| C | Copy to new buffer | O(n) | O(n) |
| C++ | std::reverse | O(n) | O(1) |
| C++ | Manual two-pointer swap | O(n) | O(1) |
| Java | StringBuilder.reverse() | O(n) | O(n) |
| Java | Char array swap | O(n) | O(n) |
| Python | s[::-1] | O(n) | O(n) |
| Python | reversed() + join | O(n) | O(n) |
The O(1)-space approaches are C and C++ in-place swaps. Java and Python always use O(n) space because their string types are immutable. If an interviewer adds the constraint “without extra memory,” give the C or C++ in-place answer.
String reversal also appears inside the palindrome check; the same index-from-both-ends pattern shows up in two-pointer array problems such as finding the smallest and largest element in an array. For the broader set of string and array problems that appear in placement coding rounds, the data structures interview questions collection covers the most-tested categories.
The complexity summary above captures a trade-off that shows up far beyond string exercises: O(1)-space in-place modification versus O(n)-space copy construction. The same decision appears in LLM application design, where keeping context lean versus building a full copy matters. TinkerLLM is where FACE Prep students move from these foundational examples to deployed LLM projects, starting at ₹299.
Primary sources
Frequently asked questions
What is the time complexity of reversing a string?
O(n) for all approaches covered here, where n is the string length. The in-place two-pointer swap performs n/2 swaps; copy-based methods create a reversed copy one character at a time.
How do you reverse a string in C without using strrev?
Use a two-pointer swap: initialise left=0 and right=strlen(s)-1, swap s[left] and s[right], then increment left and decrement right until the pointers meet. This works in-place and requires no extra buffer.
What is the difference between in-place and copy-based string reversal?
In-place reversal modifies the original string and uses O(1) extra space. Copy-based reversal creates a new reversed string and uses O(n) extra space. C char arrays support in-place modification; Python and Java strings are immutable so every reverse produces a new object.
Can you reverse a string in Java without StringBuilder?
Yes. Convert to a char array with toCharArray(), apply the two-pointer swap on the array, then construct a new String with new String(arr). This avoids the StringBuilder object allocation but still uses O(n) space because Java strings are immutable.
How does Python slice notation s[::-1] reverse a string?
Extended slice syntax with step -1 reads the string from the last character to the first, producing a new reversed string. Start and stop are omitted so the slice covers the entire string.
Why does C++ std::reverse run in O(1) space?
std::reverse performs in-place swaps on the iterator range passed to it. It holds only two iterators and a temporary swap variable regardless of string length, so extra space stays constant.
A self-paced playground for building with LLMs.
TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.
Try TinkerLLM (₹299 launch)