Good afternoon! Here's our prompt for today.
Hey there, welcome to the challenges portion of the AlgoDaily technical interview course! Over the next few days, you'll get some hands-on experience with the essential data structures and algorithms that will help you nail your interview, and land your dream software engineering job.
The only way to get better at solving these problems is to power through a few.
We covered the best ways to prepare in this lesson, in this one, and here. Be sure to visit those if you need some more guidance. Otherwise, let's jump into it.
Reverse a String
Let's reverse a string!

We'll usually start with a simple prompt, as you would in a regular technical interview. Like most, this one will be intentionally open-ended.
Prompt
Can you write a function that reverses an inputted string without using the built-in Array#reverse
method?
Let's look at some examples. So, calling:
reverseString("jake")
should return "ekaj"
.
reverseString("reverseastring")
should return "gnirtsaesrever"
.

Constraints
- Do not use the built-in
#reverse() method
or[::-1]
if Python - Ideal solution would run in
O(n)
time complexity andO(1)
space complexity
Try to solve this here or in Interactive Mode.
How do I practice this challenge?
xxxxxxxxxx
var assert = require('assert');
function reverseString(str) {
// reverse str
return str;
}
try {
assert.equal(
reverseString('njnschnjkdasn j32 uida'),
'adiu 23j nsadkjnhcsnjn'
);
console.log(
'PASSED: ' +
"`reverseString('njnschnjkdasn j32 uida')` should return `'adiu 23j nsadkjnhcsnjn'`"
);
} catch (err) {
console.log(err);
}
try {
assert.equal(reverseString('timbuktu12'), '21utkubmit');
console.log(
'PASSED: ' + "`reverseString('timbuktu12')` should return `'21utkubmit'`"
);
} catch (err) {
console.log(err);
}
try {
assert.equal(reverseString(''), '');
console.log('PASSED: ' + "`reverseString('')` should return `''`");
} catch (err) {
console.log(err);
}
try {
assert.equal(reverseString('reverseastring'), 'gnirtsaesrever');
console.log(
'PASSED: ' +
"`reverseString('reverseastring')` should return `'gnirtsaesrever'`"
);
} catch (err) {
console.log(err);
}
Here's a video of us explaining the solution.
To change the speed of the video or see it in full screen, click the icons to the right of the progress bar.
Here's our guided, illustrated walk-through.
How do I use this guide?
Let's test your knowledge. Is this statement true or false?
In Java, C#, JavaScript, Python and Go, strings are immutable
. This means the string object's state can't be changed after creation.
Press true if you believe the statement is correct, or false otherwise.
On Interviewer Mindset
Today on AlgoDaily, we're going to reverse a string. Reversing a string is one of the most common technical interview questions that candidates get. Interviewers love it because it's deceptively simple. After all, as a software engineer, you'd probably call the #reverse
method on your favorite String
class and call it a day!
So don't overlook this one-- it appears a surprising amount as a warm-up or build-up question. Many interviewers will take the approach of using an easy question like this one, and actually judge much more harshly. You'll want to make you sure really nail this.
How We'll Begin Solving
We want the string reversed, which means that we end up with all our letters positioned backwards. If you need a quick review of string
s, check out our lesson on arrays and strings.
We know that string
s can be thought of as character arrays-- that is, each element in the array is a single character. And if we can assume that, then we know the location (array position) of each character, as well as the index when the array
ends.
There's a caveat to thinking of strings as character arrays-- it's not always true. As readers and viewers have pointed out, a string represents text formed from graphemes (the smallest functional unit of a writing system)-- formed by combining character sequences in unicode.
Though strings and arrays contain similar methods like length
, concat
, and character position access-- they are not identical. As an example, arrays are mutable and strings usually are not. Before we can operate on the string as an array, we'll need to separate the units (in JS by calling the .split()
method, or bypass this property by generating a brand new string instead of trying to operate on the original.
However, after the split
operation, we can apply that paradigm to operating on this string. Thus we can step through each of its indices. Stepping through the beginning of the string, we'll make these observations at each point:

1const str = "JAKE";
2// position 0 - "J"
3// position 1 - "A"
4// ...
Since a reversed string is just itself backwards, a brute force solution could be to use the indices, and iterate from the back to the front.
See the code attached and try to run it using Run Sample Code
. You'll see that we log out each character from the back of the string!
xxxxxxxxxx
function reverseString(str) {
let newString = '';
// start from end
for (let i = str.length-1; i >= 0; i--) {
console.log('Processing ', newString, str[i]);
// append it to the string builder
newString = newString + str[i];
}
// return the string
return newString;
}
console.log(reverseString('test'));
Build your intuition. Fill in the missing part by typing it in.
We want to console.log
out:
15
24
33
42
51
What's the missing line here?
1var arr = [1, 2, 3, 4, 5];
2
3for (var i = ___________; i >= 0; i--) {
4 console.log(arr[i]);
5}
Write the missing line below.
Can We Do Better Than Brute Force?
However, it wouldn't really be an interesting algorithms question if there wasn't a better way. Let's see how we can optimize this, or make it run faster. When trying to make something more efficient, it helps to think of things to cut or reduce.
One thing to note is that we're going through the entire string-- do we truly need to iterate through every single letter?
Let's examine a worst case scenario. What if the string is a million characters long? That would be a million operations to work through! Can we improve it?
Yes, With More Pointers!
Well, we're only working with a single pointer right now. The iterator from our loop starts from the back, and appends each character to a new string, one by one. Having gone through The Two Pointer Technique, we may recognize that some dramatic improvements can be had by increasing the number of pointers we use.
By this I mean, we can cut the number of operations in half. How? What if we did some swapping instead? By using a while
loop and two pointers-- one on the left and one on the right.
With this in mind-- the big reveal is that, at each iteration, we can swap the letters at the pointer indices. After swapping, we would increment the left
pointer while decrementing the right
one. That could be hard to visualize, so let's see a basic example listed out.
1jake // starting string
2
3eakj // first pass
4^ ^
5
6ekaj // second pass
7 ^^
Build your intuition. Click the correct answer from the options.
What's a good use case for the two pointers technique?
Click the option that best answers the question.
- Shifting indices to be greater at each iteration
- Reducing a solution with a nested for-loop and O(n^2) complexity to O(n)
- Finding pairs and duplicates in a for-loop
- None of these
With two pointers, we've cut the number of operations in half. It's much faster now! However, similar to the brute force, the time complexity is still O(n)
.

Why Is This?
Well, if n
is the length of the string, we'll end up making n/2
swaps. But remember, Big O Notation
isn't about the raw number of operations required for an algorithm-- it's about how the number scales with the input.
So despite requiring half the number operations-- a 4
-character string would require 2
swaps with the two-pointer method. But an 8
-character string would require 4
swaps. The input doubled, and so did the number of operations.
If you haven't by now, try to do the problem before moving on.
One Pager Cheat Sheet
- Get your feet wet with hands-on experience of essential data structures and algorithms by completing the
reverseString
challenge as a way to power through the AlgoDaily technical interview course and set yourself up for success in landing your dream software engineering job. - Strings are
immutable
, sotransformation algorithms
are necessary to create anew string object
when performing operations like reversing a string, preserving the original string and its properties. - Reverse a string is one of the most common interview questions for software engineers, and though it seems simple, a brute force solution can be done by iterating from the back to the front using string indices.
- We can use a
for loop
toconsole.log
out each element of the arrayarr
from the end to the start, decrementing the index position by 1 each time the loop is iterated, beginning witharr.length - 1
. - We can optimize the string reversal brute force approach by using the Two Pointer Technique with a
while
loop and swapping letters at each iteration, reducing the number of operations required by half. - The
two pointers technique
can be used to reduce the complexity of a nested for-loop fromO(n^2)
toO(n)
, significantly improving the efficiency of a solution. - The time complexity of reversing a string using two pointers is still
O(n)
, as the number of swaps increases in proportion to the input size.
This is our final solution.
To visualize the solution and step through the below code, click Visualize the Solution on the right-side menu or the VISUALIZE button in Interactive Mode.
xxxxxxxxxx
var assert = require('assert');
function reverseString(str) {
let strArr = str.split('');
let start = 0;
let end = str.length - 1;
while (start <= end) {
const temp = strArr[start];
strArr[start] = strArr[end];
strArr[end] = temp;
start++;
end--;
}
return strArr.join('');
}
try {
assert.equal(
reverseString('njnschnjkdasn j32 uida'),
'adiu 23j nsadkjnhcsnjn'
);
console.log(
'PASSED: ' +
"`reverseString('njnschnjkdasn j32 uida')` should return `'adiu 23j nsadkjnhcsnjn'`"
);
} catch (err) {
console.log(err);
}
try {
assert.equal(reverseString('timbuktu12'), '21utkubmit');
console.log(
'PASSED: ' + "`reverseString('timbuktu12')` should return `'21utkubmit'`"
);
} catch (err) {
console.log(err);
}
try {
assert.equal(reverseString(''), '');
console.log('PASSED: ' + "`reverseString('')` should return `''`");
} catch (err) {
console.log(err);
}
try {
assert.equal(reverseString('reverseastring'), 'gnirtsaesrever');
console.log(
'PASSED: ' +
"`reverseString('reverseastring')` should return `'gnirtsaesrever'`"
);
} catch (err) {
console.log(err);
}
You're doing a wonderful job. Keep going!
If you had any problems with this tutorial, check out the main forum thread here.