How to Reverse a String in Java using Recursion
โก Smart Summary
Reversing a string in Java with recursion works by peeling off the first character, reversing whatever remains, and appending that first character to the end. An empty string stops the calls and unwinds the stack.
In this example program, we will reverse a string entered by a user.
We will create a function to reverse a string. Later we will call it recursively until all characters are reversed. Recursion suits this problem because a reversed string is simply the reversed tail of the string with the original first character stuck on the end, which is the same problem one character smaller.
Write a Java Program to Reverse String
The class below declares the input in main(), hands it to reverseString(), and prints what comes back. Two println() calls inside the method make each recursive step visible in the console.
package com.guru99; public class ReverseString { public static void main(String[] args) { String myStr = "Guru99"; //create Method and pass and input parameter string String reversed = reverseString(myStr); System.out.println("The reversed string is: " + reversed); } //Method take string parameter and check string is empty or not public static String reverseString(String myStr) { if (myStr.isEmpty()){ System.out.println("String in now Empty"); return myStr; } //Calling Function Recursively System.out.println("String to be passed in Recursive Function: "+myStr.substring(1)); return reverseString(myStr.substring(1)) + myStr.charAt(0); } }
Code Output:
Each line of the output is one recursive call. The tail printed on every line is one character shorter than the line above it, and the final line shows the reversed result.
String to be passed in Recursive Function: uru99 String to be passed in Recursive Function: ru99 String to be passed in Recursive Function: u99 String to be passed in Recursive Function: 99 String to be passed in Recursive Function: 9 String to be passed in Recursive Function: String in now Empty The reversed string is: 99uruG
How the Recursive Reversal Works Step by Step
Two lines carry the whole method. The base case, if (myStr.isEmpty()), gives the recursion somewhere to stop. The recursive line, return reverseString(myStr.substring(1)) + myStr.charAt(0), splits the work in two: substring(1) is everything after the first character, and charAt(0) is that first character, appended after the reversed remainder.
Tracing the input Guru99 makes the order clear. Java pushes one frame for each call before any concatenation happens:
| Call | myStr | Passed to the next call | Expression waiting to finish |
|---|---|---|---|
| 1 | Guru99 | uru99 | reverseString(“uru99”) + G |
| 2 | uru99 | ru99 | reverseString(“ru99”) + u |
| 3 | ru99 | u99 | reverseString(“u99”) + r |
| 4 | u99 | 99 | reverseString(“99”) + u |
| 5 | 99 | 9 | reverseString(“9”) + 9 |
| 6 | 9 | (empty) | reverseString(“”) + 9 |
| 7 | (empty) | base case reached | returns the empty string |
The stack then unwinds from the bottom up, and each frame appends its saved character: the empty string becomes 9, then 99, then 99u, 99ur, 99uru, and finally 99uruG. Because Java strings are immutable, none of these intermediate values overwrites the previous one โ every concatenation allocates a new String object.
Two details in the console output are worth naming. The sixth line ends with nothing after the colon, because substring(1) on a one-character string returns the empty string rather than null. The message that follows reads “String in now Empty” in the original program; the wording is a typo for “String is now empty” and has been left untouched so the code and the output above still match line for line.
Other Ways to Reverse a String in Java
Recursion is the clearest way to see the reversal happen, but it is rarely the way production code does it. Three alternatives cover almost every real case.
1. StringBuilder.reverse() is the shortest and the fastest. The class carries a built-in reverse() method, so the whole job fits on one line:
String reversed = new StringBuilder(myStr).reverse().toString();
2. A for loop with charAt() walks the string backwards from the last index to zero. Interviewers often ask for this version because it shows the logic instead of delegating it:
String reversed = ""; for (int i = myStr.length() - 1; i >= 0; i--) { reversed = reversed + myStr.charAt(i); }
3. A two-pointer swap over toCharArray() converts the string to a char array, then trades the outermost characters inwards until the pointers meet in the middle:
char[] chars = myStr.toCharArray(); int left = 0; int right = chars.length - 1; while (left < right) { char temp = chars[left]; chars[left] = chars[right]; chars[right] = temp; left++; right--; } String reversed = new String(chars);
The same array technique reverses a numeric sequence or any other ordered collection, which is why it turns up in Java array exercises as often as in string ones.
Time and Space Complexity of Each Approach
The four versions do not cost the same. Both quadratic entries below share one cause: they create a brand-new String on every step, and copying n characters n times is n squared work.
| Approach | Time | Extra space | Why |
|---|---|---|---|
| Recursion with substring() | O(n²) | O(n²) | substring() copies the remaining characters on every call, and one stack frame is held per character |
| for loop with charAt() and + | O(n²) | O(n²) | Each concatenation allocates a new String and copies everything gathered so far |
| StringBuilder.reverse() | O(n) | O(n) | One mutable buffer, one pass, and surrogate pairs are kept intact |
| Two pointers over toCharArray() | O(n) | O(n) | One array copy, then n/2 swaps with no further allocation |
Pick the recursive version to learn or to demonstrate how the call stack behaves, the char-array version when an interviewer asks for the logic by hand, and StringBuilder.reverse() in anything that ships. The same trade-off between a teaching solution and a production one shows up across the classic exercises, from bubble sort and the Fibonacci series to prime number checks; each one is worth practising in Java both ways.
