forked from rohan-paul/Awesome-JavaScript-Interviews
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreverse-string-multiple-ways.js
125 lines (90 loc) · 4.7 KB
/
reverse-string-multiple-ways.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* 1st Approach -
split() method splits a String object into an array of string by separating the string into sub strings.
reverse() method reverses an array in place.
join() method joins all elements of an array into a string.*/
function reverseString(str) {
return str.split("").reverse().join("");
}
// console.log(reverseString("hello"));
// 2-nd Approach - Using Recursion.
function reverseStringRecursive(str) {
if (str === "") {
return "";
} else {
return reverseStringRecursive(str.substr(1)) + str.charAt(0);
}
}
// Shorter version of above
rev = s => (!s) ? '' : rev(s.substr(1)) + s.charAt(0)
console.log(rev("hello")); // => olleh
/*
A> Per the standard mechanism of recursion, for the single line of code, where I am calling the same function, I will not have a single code to execute, but several nested calls that will stack up with each call. And the end of that line's execution, it will just return the top most nested call in the stack.
B> With each recursive call the stack will build up as below..
recursionStringReverse('hello')
(recursionStringReverse('ello') + 'h')
((recursionStringReverse('llo') + 'e') + 'h')
(((recursionStringReverse('lo') + 'l') + 'e') + 'h')
((((recursionStringReverse('o') + 'l') + 'l' ) + 'e') + 'h')
(((('o') + 'l') + 'l' ) + 'e') + 'h')
That's it, terminal case reached and the most highly nested call returns immediately, which is the last line above
https://medium.com/@patelhemil/an-interview-question-how-many-ways-can-you-reverse-a-string-in-javascript-89e8d6f5fa1d -
This method is one of the best in space and time complexity. Also, using this method in the interview shows that you are a seasoned programmer. Also, mention to your interviewer that there is a risk involved in using recursion, since JavaScript currently doesn’t have tail optimization available, you will get stack overflow error if your string is more that few thousand characters.
*/
//Alternative-3-Using temporary variable
/* The substring() method extracts the characters in a string between "start" and "end", not including "end" itself. Start is position (i.e. index number) where to start the extraction. First character is at index 0 */
function reverseStr3(str) {
let i = str.length;
let temp = '';
while (i > 0) {
temp += str.substring(i-1, i)
i--;
}
return temp;
}
// console.log(reverseStr3("hello"));
//Alternative-4 - Simply pushing the characters from the last position. So, I have to start from index position (str.length -1) i.e. the last index, and after all iteration reach to the first position i.e. index-no 0
function reverseString4 (str) {
let temp = [];
for (var i = 1, len = str.length; i <= len; i++ ) {
temp.push(str.charAt(len - i));
}
return temp.join('');
}
// console.log(reverseString4("hello"));
/* Alternative-5 Uses swap method to reverse; need to traverse only half of the array. Effective for long string.
A> With each iteration, I am taking the the upper half’s value (calculated by deducting the current position by the string length), which is then temporary stored in a temp variable.
B> Then swap that value with the lower half’s value. So, for the fist iteration, I will replace, the last element with the first element of the array.
C> In the next iteration, I will swap the second last upper half element, with second last lower-half element.
D> So, we only need to traverse half of the array, to swap all the lower and upper half element.
*/
function reverseStringHalfIndex(str) {
let strArr = str.split('');
let len = strArr.length;
let halfIndex = Math.floor(len / 2) - 1;
let tmp = [];
for (var i = 0; i <= halfIndex; i++) {
tmp = strArr[len - i - 1];
strArr[len - i - 1] = strArr[i]; // So for the first iteration I am doing str[len - 1] = str[0]
strArr[i] = tmp;
}
return strArr.join('');
}
// Alternative-6 - Uses the new for-of syntax of ES6 which traveses through each element / char of an iterable object from index=0 to the last element / char
function reverseString (str) {
let reverse = "";
for (character of str) {
reverse = character + reverse;
}
return reverse;
}
// console.log(reverseString("Rohan"));
// Alternative-7 - Uses the same above for-of syntax of ES6 which traveses through each element / char of an iterable object from index=0 to the last element / char, but with reduce, and the first accumulator passed to recuce () is an empty string ''
function reverseStr(str) {
return str.split('').reduce ((accumulator, currentElm) => {
return currentElm + accumulator;
}, '')
}
console.log(reverseStr("rohan"));
// Improved version of alt-7 I dont need the split() at all
const reverseStr_Improved = s => [...s].reduce((a, c) => c + a)
console.log(reverseStr_Improved("rohan"));