+ to convert string to number
// + sign to convert string to number if possible
console.log(200 + "200"); //200200
console.log(200 + +"200"); //400
console.log(200 + +"sda"); //NaN
comibinations of the string
//input string -test
//output should be --> ['t','te','tes','test','e','es','est','s','st','t']
let combinations = (str) => {
var final = [];
for (var i = 0; i < str.length; i++) {
for (var j = i + 1; j < str.length + 1; j++) {
final.push(str.slice(i, j));
}
}
return final;
};
console.log(combinations("test"));
/*Explanations
As you know in slice -->last index is exclusive and first index is inclusive
so it will exclude the last index ..
so for example
"test".slice(0,1) ==>t
0th index will be included -->t
1st index is excluded --> e is excluded ...
******ITERATIONS**
i=0,j=1 to 4
"test".slice(0,1) ==>t
"test".slice(0,2) ==>te
"test".slice(0,3) ==>tes
"test".slice(0,4) ==>test
i=1,j=2 to 4
"test".slice(1,2) ==>e
"test".slice(1,3) ==>es
"test".slice(1,4) ==>est
i=2,j=3 to 4
"test".slice(2,3) ==>s
"test".slice(2,4) ==>st
i=3,j=4 to 4
"test".slice(3,4) ==>t
*/
Extension method to captialize the first letter of string
String.prototype.CapitalizeFirstLetter = function () {
return this[0].toUpperCase() + this.substring(1);
};
console.log("test".CapitalizeFirstLetter());
//Output:- Test
Capitalize the first letter
//Capitalize the first letter
//Input :- this is random sentence
//Expected Output:- This is random sentence
let randomSentence = "this is random sentence";
//randomSentence.substring(1) will skip first letter and give rest part..
//his is random sentence
console.log(
`%c ${randomSentence[0].toUpperCase() + randomSentence.substring(1)}`,
"color:red;font-size:20px"
);
check if string input is number - using regex
//To check if a string is a number or not
//VALID CASES
/*
23-->true
-23-->true
23..-->false --> double decimal
23.23. --> false --> double decimal
.23 -->true
-.23 --> true
sdfsfsf --> false
23. -->true -- this should be handled as well coz --> isNaN(23.) is false
*/
function isNumeric(value) {
let validation1 = /^(-?)((\.)\d+)$/.test(value);
let validation2 = /^(-?)\d+(\.)?(\d?)+$/.test(value);
if (validation1 || validation2) return true;
return false;
}
console.log(`%c ${isNumeric("23")}`, "color:red;font-size:20px"); //true
console.log(`%c ${isNumeric("-23")}`, "color:red;font-size:20px"); //true
console.log(`%c ${isNumeric("23..")}`, "color:red;font-size:20px"); //false
console.log(`%c ${isNumeric(".23")}`, "color:red;font-size:20px"); //true
console.log(`%c ${isNumeric("-.23")}`, "color:red;font-size:20px"); //true
console.log(`%c ${isNumeric("dsdff")}`, "color:red;font-size:20px"); //false
console.log(`%c ${isNumeric("23.23.")}`, "color:red;font-size:20px"); //false
console.log(`%c ${isNumeric("23.")}`, "color:red;font-size:20px"); //true
/*explanation
validation1 --> /^(-?)((\.)\d+)$/ -->handles .232312
? -> means optional , so - is optional -->for negative values
\d+ -> -if the number starts with decimal --> it has to be followed by digits
+symbol near d --> means --> .3433 --> you can enter multiple digits
suppose you remove + --> then you can do only .3 --> only one digit
validation2 --> /^(-?)\d+(\.)?(\d?)+$/ --> handles 23.1212
Again ? - means optional , so - is optional -->for negative values
Number can start with digit --can be multiple digits --> \d+
Followed by single . decimal ...it is optional --> as number can be whole number as well so optional
Then followed by digits .. I kept optional coz --> we wanted to handle 23. --> even this should be true ..thats why ? is there in \d?
At the end + --> coz if numbers exists it can be multiple ...
*/
check if string input is number - second way
function isNumeric1(str) {
if (typeof str != "string") return false;
return !isNaN(str) && !isNaN(parseFloat(str));
}
console.log(`%c ${isNumeric1("23")}`, "color:red;font-size:20px"); //true
console.log(`%c ${isNumeric1("-23")}`, "color:red;font-size:20px"); //true
console.log(`%c ${isNumeric1("23..")}`, "color:red;font-size:20px"); //false
console.log(`%c ${isNumeric1(".23")}`, "color:red;font-size:20px"); //true
console.log(`%c ${isNumeric1("-.23")}`, "color:red;font-size:20px"); //true
console.log(`%c ${isNumeric1("dsdff")}`, "color:red;font-size:20px"); //false
console.log(`%c ${isNumeric1("23.23.")}`, "color:red;font-size:20px"); //false
console.log(`%c ${isNumeric1("23.")}`, "color:red;font-size:20px"); //true
string rotation - Attempt 1
// String Rotation
// Question --> Verify if the given string is any of the string rotation of original string
// For example --> 'lohel' is one of the string rotation of 'hello'
// But 'heoll' is not one of the string rotation of 'hello'
// take the last character ..make it first
// loop rest of characters to append.. make this string as new string
// o+ hell -->ohell = inputStr
// l+ ohel -->lohel = inputStr
// l+lohe -->llohe = inputStr
// e+lloh -->elloh = inputStr
// h+ello -->hello .. the last one will be back to original string
const isStringRotation = (originalStr, inputStr) => {
let length = inputStr.length - 1;
let temp;
for (let j = 0; j <= length - 1; j++) {
let i = 0;
temp = inputStr[length];
while (i < length) {
temp += inputStr[i];
i++;
}
//console.log(temp);
inputStr = temp;
if (inputStr === originalStr) return true;
}
return false;
};
console.log(isStringRotation("hello", "elloh")); //true
console.log(isStringRotation("hello", "heoll")); //false
string rotation - Attempt 2
/*Find the index of the input string
originalStr = 'hello'
inputStr ='llohe'
1. pick the first letter of inputStr - l
2. find the index of l in originalStr ==> 2 and 3
3. construct new string from the originalStr.. based on the index ...
a) so here if index is 2 ==> llohe
b) if index is 3 ==> lohel
3.a) matches with the input string -- no need to loop for index 3 ...
*/
const isStringRotation = (originalStr, inputStr) => {
if (originalStr.length !== inputStr.length) return false;
let output = false;
let firstletter = inputStr[0];
let indexes = originalStr
.split("")
.map((v, i) => {
if (originalStr[i] === firstletter) {
return i;
}
})
.filter((y) => y >= 0);
for (let i = 0; i < indexes.length; i++) {
console.log(indexes[i]);
const newString =
originalStr.substring(indexes[i], originalStr.length) + originalStr.substring(0, indexes[i]);
console.log(newString);
if (newString === inputStr) {
output = true;
break;
}
}
return output;
};
console.log(isStringRotation("hello", "ohell")); //true
console.log(isStringRotation("hello", "elloz")); //false
string rotation - Attempt 3
let string = "hello";
let inputstring1 = "ohell";
let inputstring2 = "ohlel";
let modifiedstring = string + string;
if (inputstring1.length !== string.length) console.log(false);
else console.log(modifiedstring.includes(inputstring1)); //true
if (inputstring1.length !== string.length) console.log(false);
else console.log(modifiedstring.includes(inputstring2)); //false
string rotation - Attempt 4
let string = "hello";
for (let i = 0; i < string.length; i++) {
console.log(string.slice(i, string.length));
}
/*
hello -1 (slice(0,5))
ello -2 (slice(1,5))
llo -3 (slice(2,5))
lo -4 (slice(3,5))
o -5 (slice(4,5))
*/
for (let i = 0; i < string.length; i++) {
console.log(string.slice(0, i));
}
/*
-1 (slice(0,0))
h -2 (slice(0,1))
he -3 (slice(0,2))
hel -4 (slice(0,3))
hell -5 (slice(0,4))
*/
/*
combine both
1+1 -->hello
2+2 -->elloh
3+3 -->llohe
4+4 -->lohel
5+5 -->ohell
*/
console.log('---------------');
for (let i = 0; i < string.length; i++) {
console.log(string.slice(i, string.length) + string.slice(0, i));
}
Anagram -- Attempt 1
A word or phrase that is made by arranging the letters of another word or phrase in a different order
//Attempt 1
const countChar = (str) => {
let map = new Map();
for (let i of str) {
map.set(i, map.get(i) ? map.get(i) + 1 : 1);
}
return map;
};
const isPermutation = (str1, str2) => {
if (str1.length === str2.length) {
let mappedChar1 = countChar(str1);
//Map(3)Â {'a' => 2, 'n' => 1, 'u' => 1}
let mappedChar2 = countChar(str2);
//Map(3)Â {'u' => 1, 'n' => 1, 'a' => 2}
let output = true;
for (const key of mappedChar1.keys()) {
if (mappedChar2.get(key) !== mappedChar1.get(key)) {
output = false;
}
}
return output;
}
return false;
};
console.log(isPermutation("anua", "unaa"));
Anagram - Attempt 2
//Attempt-->2
const isPermutation = (str1, str2) => {
//convert string to array
let str1Array1 = str1.split("");
let str1Array2 = str2.split("");
let map = new Map();
if (str1.length === str2.length) {
for (let y of str1) {
//dont loop for already looped character...
if (map.get(y)) {
continue;
} else map.set(y, true);
//count of character length in that array1 and array2...
//if count mismatches - return...
let str1CountChar = str1Array1.filter((x) => x === y).length;
let str2CountChar = str1Array2.filter((x) => x === y).length;
if (str1CountChar !== str2CountChar) return false;
}
return true;
}
return false;
};
console.log(isPermutation("pnuragaaga", "garunaaaag")); //false
console.log(isPermutation("anurag", "garuna")); //true
Anagram - attempt 3
//attempt3
const isPermutation = (str1, str2) => {
return str1.split("").sort().join("") === str2.split("").sort().join("");
};
console.log(isPermutation("anurag", "garuna"));
console.log(isPermutation("ppnurag", "garuna"));
Reverse string -- split , reverse and join - Attempt 1
let name = "anurag";
console.log(name.split("").reverse().join(""));
Reverse string -- using spread operator, reverse , join - Attempt 2
let name = "anurag";
console.log([...name].reverse().join(""));
Reverse string using forloop - Attempt 3
let name = "anurag";
for (let i = name.length - 1; i >= 0; i--) {
finalname += name[i];
}
console.log(finalname);
Reverse using charAt - Attempt 4
let name = "anurag";
let length = name.length - 1;
let finalname = "";
while (length >= 0) {
finalname += name.charAt(length);
length--;
}
console.log(finalname);
//Explanation
//name.charAt(5) - g
Reverse string using substr and slice
let name = "anurag";
let length = name.length - 1;
let finalname = "";
while (length >= 0) {
finalname += name.substr(length);
name = name.slice(0, -1);
length--;
}
console.log(finalname);
/*Explanation
name.substr(5)-g
name.substr(4)-ag
name.substr(3)-rag
first iteration
so we do this as below
name.substr(5)-g
then slice the name from - anurag to anura
second iteration
name.substr(4)-a
then slice the name from - anura to anur
..and so on
*/
Reverse string using recursion
const reverseString = (str) => {
return str === "" ? "" : reverseString(str.substr(1)) + str.charAt(0);
};
let x = reverseString("anurag");
console.log(x);
Pallindrom of a number
// Pallindrome 1
let number = 12321;
//let number = 123321;
let x = number.toString();
let isPallindrome = true;
for (let i = 0; i < x.length / 2; i++) {
if (x[i] !== x[x.length - 1 - i]) {
isPallindrome = false;
}
}
if (isPallindrome) {
console.log("is pallindrome");
} else {
console.log("is not pallindrome");
}
// Pallindrome 2
let number = 123321;
//let number = 12321;
let original = number;
let revnum = 0;
while (number > 0) {
let rem = number % 10;
number = Math.floor(number / 10);
revnum = revnum * 10 + rem;
}
if (revnum === original) {
console.log("is pallindrome");
} else {
console.log("is not pallindrome");
}
// Pallindrome 3
let number = 123321;
//let number = 12321;
let length = number.toString().length;
let firstHalfNumber = number.toString().substring(0, length / 2);
let i = 1;
let lastHalfRevnum = 0;
while (i <= length / 2) {
let rem = number % 10;
number = Math.floor(number / 10);
lastHalfRevnum = lastHalfRevnum * 10 + rem;
i++;
}
if (firstHalfNumber === lastHalfRevnum.toString()) {
console.log("is pallindrome");
} else {
console.log("is not pallindrome");
}
Length of Number without converting to string
//calculate the length of number without using .toString()
let number = 12345;
let length = 0;
while (number !== 0) {
number = Math.floor(number / 10);
length++;
}
console.log(length);
Panagram
Panagram - if all the 26 alphabets are contained in the string then its Panagram
//1. USING INCLUDES OF String
const test1 = (str) => {
const strUpper = str.toUpperCase();
for (let i = 65; i <= 90; i++) {
if (!strUpper.includes(String.fromCharCode(i))) {
return false;
}
}
return true;
};
// String.fromCharCode(65); A
// String.fromCharCode(66); B
// String.fromCharCode(67); C
// String.fromCharCode(68); D
// String.fromCharCode(69); E
// String.fromCharCode(70); F
// String.fromCharCode(71); G
//////////////////////////////////////////////////////////
//2.USING ARRAY
const test2 = (str) => {
str = str.toUpperCase();
const array = new Array(26).fill(false);
for (let i = 0; i < str.length; i++) {
if (str[i] >= "A" && str[i] <= "Z") {
let index = str.charCodeAt(i) - "A".charCodeAt(0);
array[index] = true;
}
}
let result = array.every((i) => i);
return result;
};
//Explanation
/*
FIRST ITERATION
"A".charCodeAt(0) = 65
Lets assume the first letter is C
str.charCodeAt(i) = 67
67-65= 2
end position becomes true
[undefined,undefined,true, undefined .......]] //length is 26
SECOND ITERATION
/*"A".charCodeAt(0) = 65
Lets assume the second letter is F
str.charCodeAt(i) = 70
70-65= 5
[undefined,undefined,true,undefined,true .......]]
*/
//////////////////////////////////////////////////////////
///3.USING MAP
const test3 = (str) => {
str = str.toUpperCase();
const alphabets = new Map();
for (let i = 0; i < str.length; i++) {
if (str[i] >= "A" && str[i] <= "Z") {
alphabets.set(str[i], true);
}
}
if (alphabets.size === 26) {
return true;
}
return false;
};
/*Explanation
alphabets.set('A',true)
alphabets.set('A',true)
alphabets.set('A',true)
alphabets.set('B',true)
Map(2) {'A' => true, 'B' => true}
it will be only two values as keys cant be repeated
so check the count after th e loop ends. if it is 26 then its panagram
*/
//////////////////////////////////////////////////////////
///4.USING SET////
const test4 = (str) => {
str = str.toUpperCase();
const alphabets = new Set();
for (let i = 0; i < str.length; i++) {
if (str[i] >= "A" && str[i] <= "Z") {
alphabets.add(str[i], true);
}
}
if (alphabets.size === 26) {
return true;
}
return false;
};
console.log(test1("TThe quick /// browns fox jump over the lazy dog"));
console.log(test2("TThe quick ,... browns fox jump over the lazy dog"));
console.log(test3("TThe quick ADD@ browns fox jump over the lazy dog"));
console.log(test4("TThe quick ADD@ browns fox jump over the lazy dog"));
Check unique chatacters in a string
O(n^2) - lastIndexOf
let name1='anurag';
console.log(name1.lastIndexOf('a'));//4
console.log(name1.lastIndexOf('n'));//1
console.log(name1.lastIndexOf('u'));//2
console.log(name1.lastIndexOf('r'));//3
console.log(name1.lastIndexOf('g'));//5
//if lastIndexOf is not equal to i ..it means the same character is present again
//when we loop .. i=0 ..lastIndexOf('a') is 4 ..
//0 not equal to 4 .. so a is present at 4th position again..
//so the string doesn't have unique character
const isUniqueCharacters = (str) => {
for (let i = 0; i < str.length; i++) { //O(n)
if (str.lastIndexOf(str[i]) !== i) return false; //O(n)
}
return true;
};
console.log(isUniqueCharacters("anurag"));
//O(n) * O(n) --> O(n^2)
SORT AND LOOP - O(nlogn)
const isUniqueCharacters = (str) => {
for (let i = 0; i < str.length; i++) {
const chars = str.split("").sort(); //* O(n * log(n)) */
//*O(n)
for (let i = 1; i < chars.length; i++) {
if (chars[i] === chars[i - 1]) return false;
}
return true;
}
};
console.log(isUniqueCharacters("anurag"));
//O(n + n * log(n)) --> O(nlogn)
USING OBJECT - KEEPING COUNT OF EACH CHARACTER
let myName = "anurag";
const isUnique = (str) => {
const finalObj = {};
for (let i of str) {
!finalObj[i] ? (finalObj[i] = 1) : finalObj[i]++;
}
return finalObj;
};
let final = isUnique(myName);
//final::- {a: 2, n: 1, u: 1, r: 1, g: 1}
//to convert object to array
// We are converting values to array here
const finalArrayValues = Object.values(final);
//fianArrayValues=[2,1,1,1,1]
console.log(finalArrayValues.every((i) => i === 1));
//OUTPUT - false
//***********Short Explanation**************
//when it loops anurag..
//First letter :-a is not there in final obj
//we get undefined...//!undefined is true
//we assign 1 finalObj['a'] =1
//next time when a comes in anurag ...
// finalObj['a'] is 1 goes to : part to increase the count
//We get final as below
//final::- {a: 2, n: 1, u: 1, r: 1, g: 1}
//pick only values- Object.values
//check if all are 1 or not
USING MAP - FETCHING VALUE - .get()
const isUnique = (str) => {
let map = new Map();
for (let i of str) {
if (map.get(i)) {
console.log(map);
return console.log("name doesn't contain unique characters");
} else map.set(i, true);
}
console.log("name contains unique characters");
};
//name contains unique characters
isUnique("ANURG"); //Map(5)Â {'A' => true, 'N' => true, 'U' => true, 'R' => true, 'G' => true}
isUnique("ANURAG");
// {'A' => true, 'N' => true, 'U' => true, 'R' => true}
// when it loops for the last A of ANURAG ... IT FINDS A IN ABOVE MAP
// IT PRINTS -> name doesn't contain unique characters
USING MAP -FETCHING KEY - .has()
const isUnique = (str) => {
let map = new Map();
for (let i of str) {
if (map.has(i)) {
console.log(map);
return console.log("name doesn't contain unique characters");
} else map.set(i);
}
console.log(map);
console.log("name contains unique characters");
};
isUnique("ANURG");
//Map(5)Â {'A' => undefined, 'N' => undefined, 'U' => undefined, 'R' => undefined, 'G' => undefined}
isUnique("ANURAG");
// Map(4)Â {'A' => undefined, 'N' => undefined, 'U' => undefined, 'R' => undefined}
// when it loops for the last A of ANURAG ... IT FINDS A IN ABOVE MAP
// IT PRINTS -> name doesn't contain unique characters
//if (map.has(i)) --> it checks the key if it is present or not
// last example map.get--> was checking the value not the key
USING SET
const isUnique = (str) => {
let set = new Set();
for (let i of str) {
if (set.has(i)) {
console.log(set);
return console.log("name doesn't contain unique characters");
} else set.add(i);
}
console.log("name contains unique characters");
};
isUnique("ANURAG");
//SET --> {'A', 'N', 'U', 'R'}
//When it encounters last A of ANURAG -->IT FINDS IN THE SET
//PRINTS --> name doesn't contain unique characters
isUnique("ANURG");
//name contains unique characters
USING SET ONE LINER
let str ="anurag";
console.log(new Set(str).size ===str.length);
ReplaceAll string
//Replace all Anurag with Abhishek
let string = "Anurag is Anurag";
console.log(string.replaceAll("Anurag", "Abhishek"));
//output:- Abhishek is Abhishek
console.log(string.replace(/Anurag/g, "Abhishek"));
//output:- Abhishek is Abhishek
Remove duplicates in a string
let name = "anurag";
//output should be anurg
//remove duplicate
const characters = new Set(name);
console.log(Array.from(characters).join(""));
TIME COMPLEXITY - O(N)
SPACE COMPLEXITY - O(N)
SPACE COMPLEXITY - O(N)