loading...
Cover image for 24-hour coding interview prep challenge

24-hour coding interview prep challenge

zahidulislam profile image Zahidul Islam ・10 min read

I am not a big believer in measuring a developer's skill based on 60 minutes of coding challenges. Most of the time those problems are designed in such a way that if you know the algorithm it will take 15 minutes to solve. I can’t remember a time when I solved a difficult real-life problem in such a short time. Every complex problem takes time to solve.

However, I have two coding interviews coming up this Monday, 6 January. So instead of complaining about the interview process, I will commit to spending 24 hours starting tomorrow morning January 4, 2020, at 8:00 AM till January 5 at 8:00 PM. During that time I will study data structures and algorithms.

I will update my progress periodically, publish notes and codes. Here are the topics I have in mind:

  • Array and String
  • Linked List
  • Stack and Queue
  • Trees
  • Graphs
  • Bit Manipulation
  • Recursion
  • Dynamic Programming
  • Searching and Sorting

I am planning to read Cracking the Coding Interview by Gayle Laakmann McDowell and Data Structures and Algorithms with JavaScript: Bringing Classic Computing Approaches to the Web by Michael McMillan.

I will read other blog posts and solve as many coding problems as I can and share them with the DEV community.

Please do share with me any good interview prep resources you know. I want this post and conversation to be a great place where anyone can refer to when they have very little time to prepare for the coding interviews.

Day 1 (January 4, 2020)

Alt Text

I started my 24-hour coding Interview prep challenge at 10:00 AM. I have a perfect cup of coffee and I am ready to crack the coding interview prep. Here are the topics I will go through today.

  • Arrays
  • String
  • Linked Lists
  • Stacks
  • Queues
  • Trees
  • Graphs
  • Search

I will study the topics, document all useful resources, solve 5/10 problems in each topic and update the community every 2 hours. I believe the community can be a great accountability partner.

Please share your best ideas on how master data structure quickly. I appreciate any suggestions.

The next update will be at 12:00 PM.

12: 00 PM Update

  • I read the first chapter of Cracking the Coding Interview book.
  • Here are the programming problems I worked on:

coding

Arrays and Strings

1. Is Unique: Implement an algorithm to determine if a string has all unique characters. What if you cannot use additional data structures?

function uniqueCharacters(str) {
  const ASCII_CHARS = 256;

  if(str.length > ASCII_CHARS) {
    return false;
  }

  const chars = Array(ASCII_CHARS).fill(false);

  for(let char of str){
    const index = char.charCodeAt(0);
    if (chars[index] === true) {
      return false;
    }
    chars[index] = true;
  }

  return true;
}

console.log(uniqueCharacters('abcd10jk')); // true
console.log(uniqueCharacters('hutg9mnd!nk9')); // false

2. Check Permutation: Given two strings, write a method to decide if one is a permutation of the other.

function isPermutation(str1, str2) {
  if (str1.length !== str2.length) {
    return false;
  }

  const map = new Map();

  for(const char of str1) {
    if(map.has(char)) {
      map.set(char, map.get(char) + 1);
    } else {
      map.set(char, 1);
    }
  }

  for(const char of str2) {
      if(map.has(char)) {
        const value = map.get(char);
        if(value === 0) {
          return false;
        } else {
          map.set(char, map.get(char) - 1);
        }
      }
  }

  for(const value of map.values()) {
    if(value !== 0) {
      return false;
    }
  }
  return true;

}

console.log(isPermutation("god", "dog")); // true

3. URLify: Write a method to replace all spaces in a string with '%20'.

function replaceSpaces(str, trueLength) {
  let output = "";
  let chars = 0;

  for(let char of str) {
    if(char !== " ") {
      chars++;
    }
  }

  let spaces = trueLength - chars;

  for(let char of str) {
    if(char === " " && spaces > 0) {
      output += "%20";
      spaces--;
    } else if(char !== " ") {
      output += char;
    }
  }

  while(spaces > 0) {
    output += "%20";
    spaces--;
  }

  return output;
}

console.log(replaceSpaces("Mr 3ohn Smith", 13)); // "Mr%203ohn%20Smith"

3. Palindrome Permutation: Given a string, write a function to check if it is a permutation of a palindrome

function isPermutationOfPalindrome(str) {
  let charCount = 0;
  let map = new Map();

  for(let char of str) {
    if (char === " ") {
      continue;
    }

    if(map.has(char)) {
      map.delete(char);
    } else {
      map.set(char, true);
    }

    charCount++;
  }

  if(charCount % 2 === 0) {
    return map.size === 0;
  } else {
    return map.size === 1;
  }
}

console.log(
  isPermutationOfPalindrome("tacoa cat") === true,
  isPermutationOfPalindrome("atco cat") === true,
  isPermutationOfPalindrome(" rac ecar rara ") === true
);

4. String Compression: Implement a method to perform basic string compression using the counts of repeated characters.

function compress (str) {
  const map = new Map();
  let result = '';

  for(const char of str) {
    if(map.has(char)) {
      map.set(char, map.get(char) + 1);
    } else {
      map.set(char, 1);
    }
  }

  for(let [key, value] of map) {
    result += key + value;
  }

  return str.lenght >= result.lenght ? str : result;
}

console.log(compress('aabcccccaaa')); // "a5b1c5"

5. Rotate Matrix: Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by 90 degrees.

function rotateMatrix(arr) {
    let n = arr.length - 1;

    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n - i; j++) {
            let temp = arr[i][j];

            arr[i][j] = arr[n - j][n - i]; // top row
            arr[n - j][n - i] = temp; // right column
        }
    }

    return arr;
}


console.log(rotateMatrix([
  [1,2,3],
  [4,5,6],
  [7,8,9]
])); 

/* 
[
    [9, 6, 3], 
    [8, 5, 2], 
    [7, 4, 1]
] 
*/

6. String Rotation; Assume you have a method isSubstrin g which checks if one word is a substring of another. Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only one call to isSubstring [e.g. "waterbottle " is a rotation oP'erbottlewat")

const isSubstring = (str1, str2) => str1.includes(str2);

function isRotation(str1, str2) {
  if(!str1 || !str2) {
    return false;
  }

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

  return isSubstring(str1 + str2, str2);
}

console.log(isRotation("waterbottle", "erbottlewat")); // true
console.log(isRotation("aacdf", "acda")); // false

7. Find the first unique character in a given string or an array

function findFirstUniqueCharacter(str) {
  if(!str) return;

  const map = new Map();

  for(let char of str) {
      if(map.has(char)) {
        map.set(char, map.get(char) + 1);
      } else {
        map.set(char, 1);
      }
  }

  for(let [key, value] of map) {
    if(value === 1) {
      return key;
    }
  }
  return "None";
}

console.log(findFirstUniqueCharacter('foobar')); // f
console.log(findFirstUniqueCharacter('aabbccdef')); // d
console.log(findFirstUniqueCharacter('aabbcc')); // 'No Unique Character Found'

3: 30 PM Update

Linked Lists

Linked List Node class

class Node {
  constructor(value, next = null) {
    this.value = value;
    this.next = next;
  }
}

Linked list print function

function print(node) {
  while(node !== null) {
      console.log('->' + node.value);
      node = node.next;
  }
}

1. Remove Dups: Write code to remove duplicates from an unsorted linked list.

function removeDups(node) {
  if(node === null) return null;

  let nodes = new Map();
  let current = node.next;
  let prev = node;
  nodes.set(node.value, 1);

  while(current !== null) {
    if(nodes.get(current.value) === 1) {
      prev.next = current.next;
    } else {
      nodes.set(current.value, 1);
      prev = current;
    }
    current = current.next;
  }
  return node;
}

let node1 = new Node(1);
let node2 = new Node(2);
let node3 = new Node(3);
let node4 = new Node(2);
let node5 = new Node(1);

node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = null;

print(removeDups(node1));

/* 
"->1"
"->2"
"->3"
*/

2. Return Kth to Last: Implement an algorithm to find the kth to last element of a singly linked list.

function KthToLast(root, n) {
  if(!root) return null;
  let current = root;
  let follower = root;

  for(let i = 0; i < n; i++) {
    current = current.next;
  }

  while(current.next !== null) {
    current = current.next;
    follower = follower.next;
  }

  return follower;
}


let node1 = new Node(1);
let node2 = new Node(2);
let node3 = new Node(3);
let node4 = new Node(4);
let node5 = new Node(5);

node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = null;

console.log(KthToLast(node1, 2).value);  // 3

3. Delete middle of linked list

function removeDups(head) {
  if(head === null) return null;

  let fast = head;
  let slow = head;
  let prev = null;

  while(fast !== null && fast.next !== null) {
    fast = fast.next.next;
    prev = slow;
    slow = slow.next;
  }

  prev.next = slow.next;

  return head;
}

let nodeA = new Node('a');
let nodeB = new Node('b');
let nodeC = new Node('c');
let nodeD = new Node('d');
let nodeE = new Node('e');
let nodeF = new Node('f');

nodeA.next = nodeB;
nodeB.next = nodeC;
nodeC.next = nodeD;
nodeD.next = nodeE;
nodeE.next = nodeF;
nodeF.next = null;

print(removeDups(nodeA)); 
/*
"->a"
"->b"
"->c"
"->e"
"->f"
*/

4. Partitioning a linked list around a given value and If we don’t care about making the elements of the list stable

function partition(head, x) {
  let tail = head;
  let current = head;

  while(current !== null) {
    let next = current.next;
    if(current.value < x) {
      current.next = head;
      head = current;
    } else {
      tail.next = current;
      tail = current;
    }
    current = next;
  }
  tail.next = null;

  return head;
}

let nodeA = new Node(3);
let nodeB = new Node(5);
let nodeC = new Node(8);
let nodeD = new Node(2);
let nodeE = new Node(10);
let nodeF = new Node(2);
let nodeH = new Node(1);

nodeA.next = nodeB;
nodeB.next = nodeC;
nodeC.next = nodeD;
nodeD.next = nodeE;
nodeE.next = nodeF;
nodeF.next = nodeH;
nodeH.next = null;

print(partition(nodeA, 5));
/*
"->1"
"->2"
"->2"
"->3"
"->5"
"->8"
"->10"
*/

5. Given a linked list where each node has two pointers, one to the next node and one to a random node in the list, clone the linked list.

function clone(node) {
  if(node === null) return node;

  let map = new Map();
  let copy = new Node(node.value);
  let current = node;
  let newHead = copy;

  map.set(current, copy);

  current = current.next;
  while(current !== null) {
    let temp = new Node(current.value);
    map.set(current, temp);
    copy.next = temp;
    copy = temp;
    current = current.next;
  }

  current = node;
  copy = newHead;

  while(current !== null) {
    if(current.randome !== null) {
      copy.random = map.get(current.random);
    } else {
      copy.random = null;
    }

    current = current.next;
    copy = copy.next;
  }

  return newHead;
}

6. Given a linked list, determine whether it contains a cycle.

function hasCycle(node) {
  if(node === null) return false;
  let slow = node;
  let fast = node.next;

  while(fast !== null && fast.next !== null) {
    if(fast === slow) return true;
    slow = slow.next;
    fast = fast.next.next;
  }

  return false;
}

let node1 = new Node(1);
let node2 = new Node(2);
let node3 = new Node(3);
let node4 = new Node(4);
let node5 = new Node(5);

node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node3;

console.log(hasCycle(node1)); // true

7. How to find the middle element of the linked list in one pass?

function findMiddle(node) {
    if(node === null) return null;
    let fast = node.next;
    let slow = node;

    while(fast !== null && fast.next !== null) {
        fast = fast.next.next;
        slow = slow.next;
    }
    console.log(slow.value);
}

let node1 = new Node(5);
let node2 = new Node(6);
let node3 = new Node(7);
let node4 = new Node(1);
let node5 = new Node(2);

node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = null;

findMiddle(node1); // 7

8. Add Two Numbers

// Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
// Output: 7 -> 0 -> 8
// Explanation: 342 + 465 = 807.

const addTwoNumbers = function(l1, l2) {
  let head = new Node(0);
  let carry = 0;
  let current = head;

  while(l1 !== null || l2 !== null ) {
    const x = l1 !== null ? l1.value : 0;
    const y = l2 !== null ? l2.value : 0;

    const sum = carry + x + y;
    carry = Math.floor(sum / 10);

    current.next = new Node(sum % 10);
    current = current.next;

    if(l1 != null) l1 = l1.next;
    if(l2 != null) l2 = l2.next;
  }

  if (carry > 0) {
    current.next = new ListNode(carry);
  }
  return head.next;
};

const node13 = new Node(3);
const node12 = new Node(4);
const node11 = new Node(2);
node11.next = node12;
node12.next = node13;
const l1 = node11; 

const node23 = new Node(4);
const node22 = new Node(6);
const node21 = new Node(5);
node22.next = node23;
node21.next = node22;
const l2 = node21;

print(addTwoNumbers(l1, l2));
/*
"->7"
"->0"
"->8"
*/

7:45 PM Update

Stacks

1. Given a stack sort the elements in the stack using no more than ane additional stack

Array.prototype.peek = function() {
  return this[this.length -1];
}

Array.prototype.isEmpty = function() {
  return this.length <= 0;
}

function sortStack(stack) {
  if(!stack || stack.length ===0) return stack;

  let newStack = [];
  newStack.push(stack.pop());

  while(!stack.isEmpty()) {
    const temp = stack.pop();
    while(!newStack.isEmpty() && temp > newStack.peek()) {
      stack.push(newStack.pop());
    }
    newStack.push(temp);
  }
  return newStack;
}

console.log(sortStack([5, 1, 3, 2, 4])); // [5, 4, 3, 2, 1]

2. Evaluate Reverse Polish Notation in Javascript

function reversePolishNotation(seq) {
  if(seq.length <= 2) {
    return;
  }

  const operands = ['+', '-', '*', '/'];
  const stack = [];
  let i = 0;

  stack.push(seq[i]);
  i++;

  while(i <= seq.length) {
    let item = seq[i];
    let index = operands.indexOf(item);

    if(index < 0) {
      stack.push(item);
    } else {
      const a = parseInt(stack.pop(), 10);
      const b = parseInt(stack.pop(), 10);

      if(index === 0) {
        stack.push(a + b);
      } 
      if(index === 1) {
        stack.push(a - b);
      }
      if(index === 2) {
        stack.push(a * b);
      }
      if(index === 3) {
        stack.push(b/a);
      }
    }
    i++;
  }

  return parseInt(stack[0], 0);
}

console.log(reversePolishNotation(["2", "1", "+", "3", "*"])) // 9
console.log(reversePolishNotation(["4", "13", "5", "/", "+"])) // 6
console.log(reversePolishNotation(["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"])) // 22
console.log(reversePolishNotation(["2", "1"])) // undefined

3. Implement a stack using javascript

function Stack() {
  this.top = null;
}

Stack.prototype.push = function (val) {
  let node = {
    data : val,
    next : null
  };

  node.next = this.top;
  this.top = node;
};

Stack.prototype.pop = function () {
  if(this.top === null) {
    return null;
  } else {
    const top = this.top;
    this.top = this.top.next;
    return top.data;
  }
};

Stack.prototype.peek = function() {
  if(this.top === null) {
    return null;
  } else {
    return this.top.data;
  }
}

var S1 = new Stack();
S1.push(5);
S1.push(6);
S1.push(7);
S1.push(8);

console.log(S1.pop()); // 8
console.log(S1.pop()); // 7

4. Queue using two stacks javascript

function Queue() {
  this.pushStack = new Stack();
  this.popStack = new Stack();
}

Queue.prototype.enqueue = function(value) {
  this.pushStack.push(value);
}

Queue.prototype.dequeue = function() {
  let popStack = this.popStack;
  let pushStack = this.pushStack;

  if(popStack.peek()) {
    const deq = popStack.pop();
    return deq;
  }

  while(pushStack.peek()) {
    popStack.push(pushStack.pop());
  }
}

const q1 = new Queue();
q1.enqueue(3);
q1.enqueue(4);
q1.enqueue(5);
q1.enqueue(6);
q1.enqueue(7);
q1.dequeue();
q1.dequeue();
q1.dequeue();

console.log(q1);

5.

function stepsToSolveTowerOfHanoi(height, from, to, via) {
  if (height >= 1) {
    // Move a tower of height - 1 to buffer peg using destination peg
    stepsToSolveTowerOfHanoi(height - 1, from, via, to);
    // Move the remaining disk to the destination peg.
    console.log(`Move disk ${height} from Tower ${from} to Tower ${to}`);
    // Move the tower of `height-1` from the `buffer peg` to the `destination peg` using the `source peg`.        
    stepsToSolveTowerOfHanoi(height - 1, via, to, from);
  }

  return;
}

stepsToSolveTowerOfHanoi(3, "A", "C", "B");
/*
"Move disk 1 from Tower A to Tower C"
"Move disk 2 from Tower A to Tower B"
"Move disk 1 from Tower C to Tower B"
"Move disk 3 from Tower A to Tower C"
"Move disk 1 from Tower B to Tower A"
"Move disk 2 from Tower B to Tower C"
"Move disk 1 from Tower A to Tower C"
*/

6. Justify if a string consists of valid parentheses

function isMatchingBrackets(str) {
  if(str.length <= 1) {
    return false;
  }

  let stack = [];
  const map = {
    '{': '}',
    '[': ']',
    '(': ')'
  };

  for(let char of str) {
    if(char === '(' || char === '[' || char === '{') {
      stack.push(char);
    } else {
      const last = stack.pop();
      if (char !== map[last]) {
        return false;
      }
    }
  }
  return stack.length === 0;
}

console.log(isMatchingBrackets("(){}")); // true
console.log(isMatchingBrackets("[{()()}({[]})]({}[({})])((((((()[])){}))[]{{{({({({{{{{{}}}}}})})})}}}))[][][]")); // true
console.log(isMatchingBrackets("({(()))}}"));  // false

Discussion

pic
Editor guide
Collapse
alexparra profile image
Alex Parra

Good luck! 👍🏻

Collapse
zahidulislam profile image