Cracking The JavaScript Coding Interview
By: Deepak Vishwakarma
Tags: JavaScript, Algorithms, Web Development, Coding, Software Engineering

Cracking The JavaScript Coding Interview

Part 1: Strings

This is the first part of a series of articles that will help you to prepare for coding challenges. In this article, I will focus on the problems related to JavaScript strings.

Prerequisite: Before going forward, I am assuming you should have basic knowledge of JavaScript. At least you should know how it works.

Note: This is not a copy of Gayle_Laakmann’s book. The book is awesome. I love reading it whenever I get time. However, some samples/questions are taken from the book. While the book solves problems using Java, I have solved the same questions with JavaScript (TypeScript).

Strings: Strings are unique and it is used for almost every data set. JavaScript strings are simple and less complex. However, that is also the problem with JavaScript. If you don't pay attention, it can lead to a memory issue. Here, I have picked some of the easy and common problems for strings.

1. Is Unique

For a given string, find all the characters in the string are unique.

There are many ways to solve this problem. The simplest using a Map of the chars. Iterate over all the characters of the string and set that in the map. If the map already has that character return false from the function.

export const isUniqueChars = (txt = "") => {

const chars = new Map<string, true>();

for (let i = 0; i < txt.length; i++) {

if (chars.has(txt.charAt(i))) return false;

chars.set(txt.charAt(i), true);

}

return true;

}; console.log(isUniqueChars("background")); // true

console.log(isUniqueChars("bawdyhouse")); // true

console.log(isUniqueChars("rhythm")); //false

You can also solve this problem using ES6/ES2015 operator.

export const isUniqueChars2 = (txt = "") => {

const chars = new Map<string, true>();

// [...txt] is equivalent of Array.from(txt)

return ![...txt].some((char) => {

if (chars.has(char)) return true;

chars.set(char, true);

});

};

console.log(isUniqueChars2("background")); // true

console.log(isUniqueChars2("bawdyhouse")); // true

console.log(isUniqueChars2("rhythm")); //false

2. Check Permutation

Given two strings, find out that one string is permuted to another or not. i.e abc and acb are permuted to each other.

The simplest solution, You can sort the strings and match both strings.

const sort = (str: string) => [...str].sort().join(); export const isPermuted = (str1: string, str2: string) => {

if (str1.length !== str2.length) return false;

return sort(str1) === sort(str2);

}; console.log(isPermuted("abc", "acb")); // true

The above solution is simple but not performant. The sorting algorithm has a complexity of n log(n). We can solve this problem by counting the number of chars. Keep the counts of all characters in one string and match with the count of chars in the other string. If it mismatch, the given strings are not a permutation of others.

export const isPermuted2 = (str1: string, str2: string) => {

if (str1.length !== str2.length) return false;

// map to keep count

const chars: { [key: string]: number } = {}; for (let i = 0; i < str1.length; i++) {

if (!chars[str1.charAt(i)]) chars[str1.charAt(i)] = 0;

chars[str1.charAt(i)]++;

} for (let i = 0; i < str2.length; i++) {

if (!chars[str2.charAt(i)]) chars[str2.charAt(i)] = 0;

chars[str2.charAt(i)]--;

if (chars[str2.charAt(i)] < 0) return false;

}

return true;

}; console.log(isPermuted2("abc", "acb")); // true

console.log(isPermuted2("abc", "acd")); // false



3. URLify/encodeURI

Given string replace all special char with its encoded value.

Yes, you can use encodeURIComponent to encode special chars. However, this example can be very useful to build util to encode any kind of string.

// map to keep track of all special chars const specialChars: { [k: string]: string } = {

"@": "%40",

" ": " %20",

"#": "%23",

"%": "%25",

"^": "%5E",

"&": "%26",

":": "%3A",

"<": "%3C",

">": "%3E",

}; export const encodeString = (txt = ""): string => {

// /\W/g is reg to find not Alphabetic chars



return txt.replace(/\W/g, (m) => specialChars[m] || "");

}; console.log(encodeString("<name:deepak>")); // %3Cname%3Adeepak%3E

You can use the same technique to build an emoji text builder.

const emojiChars: { [k: string]: string } = {

love: "💚",

india: "🇮🇳",

i: "ℹ️",

};

const WORD_REG = /(\w+)/g;

export const encodeString2 = (txt = ""): string => {

return txt.replace(WORD_REG, (_, m) => emojiChars[m.toLowerCase()] || "");

}; console.log(encodeString2("I love India")); // ℹ️ 💚 🇮🇳

Here in the above solution, I am using regex to tokenize words and replace them with their emoji.

4. String Compression

Write a program to compress a string replacing repetitive chars with its count. ie. aaabbbb => a3b4.

The solution to this problem is can be tricky and simple. We can use match and repeat regex to tokenize string and replace method of the string with HOC function.

export const compress = (txt = "") => {

return txt.replace(/(\w)(\1+)/g, (_, m1, m2) => `${m1}${m2.length + 1}`);

}; console.log(compress("aaabbbb")); // a3b4

Another solution could be, iterate through chars and count the consecutive chars. /(\w)(\1+)/g is the regex to find all char and match repetition(\1). `\1` indicates repetition of matched char previously

5. Abbreviation

Create an abbreviation function, which takes a string and returns a string while taking the first and last char and replace the remaining chars with the number of chars. For example, internationalization will become i18n.

const abbrev = (text: string = "") => {

if (text.length < 3) return text;

const first = text.charAt(0);

const last = text.slice(-1);

const remLen = text.length - 2;

return `${first}${remLen}${last}`;

}; console.log(abbrev("internationalization")); // i18n

In the above solution, I have use methods String.charAt and String.slice to get first and last char respectively. We can use charAt instead of slice. But in that case, we need to find the last index and do some calculations. I am also using ES2015 template string to append string.

Let’s make this a little complex while adding more edge cases. Let’s convert the function which can take a group of words separated by special chars. i.e. I love javascript! will become I l2e j8t!

const word = /\w+/g;

const abbrevPlus = (text: string = "") => {

return text.replace(word, (matched: string) => abbrev(matched));

}; console.log(abbrevPlus("I love javascript!")); // I l2e j8t!

Here in the above solution, we are using String.replace method which accepts a RegExp and a callback function/higher-order function to find all the valid word and replace with its abbreviation. Just nice! Looks simpler than splitting and joining back.

Hope you will like the article, please let me know in case you have some common problem to be solved as part of samples.