0% found this document useful (0 votes)
12 views71 pages

DSA (Udemy Colt)

The document contains implementations of various data structures and algorithms, including a Max Binary Heap, Binary Search Tree, Bubble Sort, Dijkstra's algorithm, Doubly Linked List, and a Graph with DFS and BFS methods. Each section provides class definitions and methods for inserting, searching, and manipulating data within these structures. The document serves as a comprehensive guide for understanding and utilizing these fundamental algorithms and data structures in programming.

Uploaded by

Manoj Gowda
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views71 pages

DSA (Udemy Colt)

The document contains implementations of various data structures and algorithms, including a Max Binary Heap, Binary Search Tree, Bubble Sort, Dijkstra's algorithm, Doubly Linked List, and a Graph with DFS and BFS methods. Each section provides class definitions and methods for inserting, searching, and manipulating data within these structures. The document serves as a comprehensive guide for understanding and utilizing these fundamental algorithms and data structures in programming.

Uploaded by

Manoj Gowda
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 71

1.

Binary_Heap
class MaxBinaryHeap {

constructor() {

this.values = [41, 39, 33, 18, 27, 12];

insert(element) {

this.values.push(element);

this.bubbleUp();

bubbleUp(){

let idx = this.values.length - 1;

const element = this.values[idx];

while(idx > 0){

let parentIdx = Math.floor((idx - 1) / 2);

let parent = this.values[parentIdx];

if(element <= parent) break;

// Swap parent and element

this.values[parentIdx] = element;

this.values[idx] = parent;

// Update idx to parent index

idx = parentIdx;
}

extractMax(){

const max = this.values[0];

const end = this.values.pop();

if(this.values.length > 0){

this.values[0] = end;

this.sinkDown();

return max;

sinkDown(){

let idx = 0;

const length = this.values.length;

const element = this.values[0];

while(true){

let leftChildIdx = 2 * idx + 1;

let rightChildIdx = 2 * idx + 2;

let rightchild,leftchild;

let swap = null;

if(leftChildIdx < length){

leftchild = this.values[leftChildIdx];

if(leftchild > element){

swap = leftChildIdx;

}
}

if(rightChildIdx < length){

rightchild = this.values[rightChildIdx];

if(

(swap === null && rightchild > element) ||

(swap !== null && rightchild > leftchild) ){

swap = rightChildIdx;

if(swap === null) break;

this.values[idx] = this.values[swap];

this.values[swap] = element;

idx = swap;

let heap = new MaxBinaryHeap();

heap.insert(55);

2. Binary_Search_Tree
class Node{

constructor(val){

this.value = val;

this.left = null;

this.right = null;
}

class BinarySearchTree{

constructor(){

this.root = null;

this.size = 0;

insert(value){

var newNode = new Node(value);

if(!this.root) {

this.root = newNode;

this.size++;

return this;

} else {

var current = this.root;

while(true){

if(value === current.value) return undefined;

if(value < current.value){

if(current.left === null){

current.left = newNode;

this.size++;

return this;

} else{

current = current.left;

}
} else if(value > current.value){

if(current.right === null){

current.right = newNode;

this.size++;

return this;

} else{

current = current.right;

search(target){

if(!this.root) return false;

var current = this.root, found = false;

while(current && !found){

if(target < current.value){

current = current.left;

} else if(target > current.value){

current = current.right;

} else{

found = true;

if(!found) return false;

return found;

}
// breadth first search

BFS(){

var data = [],

queue = [],

node = this.root;

queue.push(node);

while(queue.length){

node = queue.shift();

data.push(node.value);

if(node.left){

queue.push(node.left);

if(node.right){

queue.push(node.right);

console.log(data);

//Depth First search

//PreOrder node -> left -> right.

DFSpreOrder(){

var data =[],

node = this.root;

function preOrder(node){
if(node === null) return; // Base case: if the node is null, return

data.push(node.value); // Visit the node (push its value to the result array)

if(node.left){ // Visit the left subtree

preOrder(node.left);

if(node.right){ // Visit the right subtree

preOrder(node.right);

preOrder(node); // Start the DFS traversal from the root

return data; // Return the DFS traversal result

// PostOrder left -> right -> node.

DFSpostOrder(){

var data =[],

node = this.root;

function postOrder(node){

if(node === null) return;

if(node.left){ // Visit the left subtree

postOrder(node.left);

if(node.right){ // Visit the right subtree

postOrder(node.right);

data.push(node.value); // Visit the node (push its value to the result array)

postOrder(node);
return data;

// PostOrder left -> node -> right.

DFSinOrder(){

var data =[],

node = this.root;

function inOrder(node){

if(node === null) return;

if(node.left){ // Visit the left subtree

inOrder(node.left);

data.push(node.value); // Visit the node (push its value to the result array)

if(node.right){ // Visit the right subtree

inOrder(node.right);

inOrder(node);

return data;

var tree = new BinarySearchTree();

// tree.root = new Node(10);

// tree.root.right = new Node(15);

// tree.root.left = new Node(7);

// tree.root.left.right = new Node(9);


tree.insert(10);

tree.insert(6);

tree.insert(15);

tree.insert(3);

tree.insert(8);

tree.insert(20);

tree.insert(14);

3. Bubble_Sort
function bubbleSort(arr) {

// ES2015 version of swap

const swap = (arr, a , b) => {

[arr[a], arr[b]] = [arr[b], arr[a]];

var noSwaps = true;

for(let i = arr.length; i > 0; i--){ //this is pass if i = 4 then 3 comparisons

noSwaps = true;

for(let j = 0; j < i - 1; j++){ // the i-1 is the comparisons.so as i goes down so does j.

console.log(arr,`${arr[j]},${arr[j+1]} Swap`)

if(arr[j] > arr[j + 1]){

// SWAP method!!

// let temp = arr[j];

// arr[j] = arr[j + 1];

// arr[j + 1] = temp;

swap(arr, j, j + 1);

noSwaps = false;

}
}

console.log("ONE PASS COMPLETE")

if(noSwaps){

console.log("noSwaps")

break;

return arr;

// see the output without the noSwaps also to understand

// bubbleSort([7,3,5,9,2,88,-5,22,532,543,12,53,16]);

bubbleSort([9,2,3,4,5,6,7,8])

4. Dijkstra’s
class priorityQ{

constructor(){

this.values = [];

enqueue(value,priority){

this.values.push({value,priority});

this.sort()

dequeue(){

return this.values.shift();

}
sort(){

this.values.sort((a, b) => a.priority - b.priority)

class weightedGraph{

constructor(){

this.adjacencyList = {};

addVertex(vertex){

if(!this.adjacencyList[vertex]) this.adjacencyList[vertex] = [];

addEdge(v1,v2,weight){

if(this.adjacencyList[v1]) this.adjacencyList[v1].push({node:v2,weight})

if(this.adjacencyList[v2]) this.adjacencyList[v2].push({node:v1,weight})

showGraph(){

for(let vertex in this.adjacencyList){

const edges = this.adjacencyList[vertex]

.map(neighbor => `${neighbor.node} (${neighbor.weight})`)

.join(", ")

console.log(`${vertex} -> ${edges}`)

}
Dijkstras(start,end){

const queue = new priorityQ();

const distances = {};

const previous = {};

let smallest,nextNode;

let path = [];

//store the initial values

for(let vertex in this.adjacencyList){

if(vertex === start){

distances[vertex] = 0;

queue.enqueue(vertex,0)

} else{

distances[vertex] = Infinity;

queue.enqueue(vertex,Infinity)

previous[vertex] = null; //set previous of start to null

} //console.log(queue,distances,previous)

//while there is something in the queue

while(queue.values.length){

smallest = queue.dequeue().value;

// console.log(smallest)

if(smallest === end){

//we have reached the end

console.log(distances)

console.log(previous)

while(previous[smallest]){
path.push(smallest);

smallest = previous[smallest]

break;

if(smallest || distances[smallest] !== Infinity){

for(let neighbor in this.adjacencyList[smallest]){

//finding the neighboring node rhe smallest node

nextNode = this.adjacencyList[smallest][neighbor]

// console.log(this.adjacencyList[smallest][neighbor]);

// calculate new distances to neighboring node

let candidate = distances[smallest] + nextNode.weight;

if(candidate < distances[nextNode.node]){

//updating new smallest distance to neighbor

distances[nextNode.node] = candidate;

//updating previous for a node how we got there.

previous[nextNode.node] = smallest;

//enqueue priority queue with new priority

queue.enqueue(nextNode.node, candidate)

// path.push(start);

// path.reverse();

return path.concat(start).reverse();
}

var graph = new weightedGraph();

graph.addVertex("A")

graph.addVertex("B")

graph.addVertex("C")

graph.addVertex("D")

graph.addVertex("E")

graph.addVertex("F")

graph.addEdge("A","B",4)

graph.addEdge("A","C",2)

graph.addEdge("B","E",3)

graph.addEdge("C","D",2)

graph.addEdge("C","F",4)

graph.addEdge("D","E",3)

graph.addEdge("D","F",1)

graph.addEdge("E","F",1)

graph.showGraph()

graph.Dijkstras("A","E")

5. Doubly_Linked_List
// Node

// -val

// -next
// -prev

class Node{

constructor(value){

this.value = value;

this.next = null;

this.previous = null;

// DoublyLinkedList

// -head

// -tail

// -length

class DoublyLinkedList{

constructor(){

this.head = null;

this.tail = null;

this.length = 0;

push(value){

var newNode = new Node(value);

if(!this.head){

this.head = newNode;

this.tail = newNode;

} else {
this.tail.next = newNode;

newNode.previous = this.tail;

this.tail = newNode

this.length++;

return this;

pop(){

if(!this.head) return null; // Empty list

var poppedNode = this.tail;

if(this.length === 1){ // If there is only one node

this.head = null;

this.tail = null;

} else{

this.tail = poppedNode.previous; // Update the tail to the previous node

this.tail.next = null; // Sever the connection to the popped node

poppedNode.previous = null; // Sever the backward link of the popped node

this.length--;

return poppedNode;

unshift(val){

var newNode = new Node(val);

if(!this.head){
this.head = newNode;

this.tail = newNode;

} else{

newNode.next = this.head;

this.head.previous = newNode;

this.head = newNode;

this.length++;

return this;

shift(){

if(!this.head) return null; // If the list is empty

var poppedNode = this.head;

if(this.length === 1){ // If there is only one node

this.head = null;

this.tail = null;

} else {

this.head = poppedNode.next; // Move head to the next node

this.head.previous = null; // Remove backward link from new head

poppedNode.next = null; // must execute regardless of whether there was one

poppedNode.next = null; // node or multiple nodes in the list.

this.length--;

return poppedNode;

}
get(index){

if(index < 0 || index >= this.length) return null;

var current;

var counter;

if(index <= this.length / 2){

// console.log("working from start");

current = this.head;

counter = 0;

while(counter !== index){

current = current.next;

counter++;

} else {

// console.log("working from end");

current = this.tail;

counter = this.length - 1;

while(counter !== index){

current = current.previous;

counter--;

return current;

set(index,val){

var foundNode = this.get(index);


if(foundNode != null){

foundNode.value = val;

return true;

return false;

insert(index,val){

if (index < 0 || index > this.length) return false; // Allow insert at this.length

if(index === 0) return !!this.unshift(val);

if(index === this.length) return !!this.push(val);

var newNode = new Node(val);

var previousNode = this.get(index - 1);

var nextNode = previousNode.next;

newNode.next = nextNode, nextNode.previous = newNode;

previousNode.next = newNode, newNode.previous = previousNode;

this.length++;

return true;

remove(index){

if(index < 0 || index >= this.length) return false;

if(index === 0) return !!this.shift(); // Use shift for head removal


if(index === this.length - 1) return !!this.pop(); // Use pop for tail removal

var removedNode = this.get(index); // Get node at index

var previousNode = removedNode.previous;

var nextNode = removedNode.next;

// Re-link the neighboring nodes

previousNode.next = nextNode;

nextNode.previous = previousNode;

// removedNode.previous.next = removedNode.next; these are the same as above

// removedNode.next.previous = removedNode.previous

// Clear removed node's pointers

removedNode.previous = null;

removedNode.next = null;

this.length--;

return removedNode.value; // Return the value of the removed node

clearAll(){

this.head = null;

this.tail = null;

this.length = 0;

return this;

show(){
var array = [];

var current = this.head;

while(current){

array.push(current.value);

current = current.next;

console.log(array);

var list = new DoublyLinkedList();

list.push(65);

list.push(75);

list.push(85);

// list.push(95);

// list.push(100);

// list.push(110);

6. DFS&BFS(Graph_Using_List)

// undirected graph

class Graph{

constructor(){

this.adjacencyList = {};

addVertex(vertex){
if(!this.adjacencyList[vertex]) this.adjacencyList[vertex] = [];

addEdge(v1,v2){

if(this.adjacencyList[v1]) this.adjacencyList[v1].push(v2);

if(this.adjacencyList[v2]) this.adjacencyList[v2].push(v1);

removeVertex(vertex){

if(this.adjacencyList[vertex]){

for(let adjacentVertex of this.adjacencyList[vertex]){

this.removeEdge(vertex, adjacentVertex);

delete this.adjacencyList[vertex];

removeEdge(v1,v2){

if(this.adjacencyList[v1]){

this.adjacencyList[v1] = this.adjacencyList[v1].filter(

v => v !== v2

);

} else return "no such vertex"

if(this.adjacencyList[v2]){

this.adjacencyList[v2] = this.adjacencyList[v2].filter(

v => v !== v1

);

}
}

DFSRecursive(vertex = "A"){

var result = [];

if(!this.adjacencyList[vertex]) return "no such vertex"

var visited = {};

const dfshelper = (v) => {

if(!v || visited[v]) return null;

visited[v] = true;

// console.log(visited)

result.push(v);

this.adjacencyList[v].forEach(neighbour => {

if(!visited[neighbour]){

dfshelper(neighbour);

})

dfshelper(vertex);

return result;

DFSIterative(vertex = "A"){

var result = [];

var stack = [vertex];


var visited = {};

var currVertex;

visited[vertex] = true;

while(stack.length){

console.log(stack)

currVertex = stack.pop();

result.push(currVertex);

this.adjacencyList[currVertex].forEach(neighbor =>{

if(!visited[neighbor]){

visited[neighbor] = true;

stack.push(neighbor);

});

return result;

BFS(vertex = "A"){

var queue = [vertex];

var visited = {};

var results = [];

let currVertex;

visited[vertex] = true;

while(queue.length){

currVertex = queue.shift()

results.push(currVertex)
//since we are using a queue we can reverse the order by removing each element and reversing
it & it gives a different order after the vertex.

// ['A', 'B', 'C', 'D', 'F', 'E'] this is for a normal queue ['A', 'C', 'B', 'F', 'D', 'E'] this is for a reverse
queue.

this.adjacencyList[currVertex].slice().reverse().forEach(neighbor =>{

if(!visited[neighbor]){

visited[neighbor] = true;

queue.push(neighbor);

})

return results;

var g = new Graph();

g.addVertex("A")

g.addVertex("B")

g.addVertex("C")

g.addVertex("D")

g.addVertex("E")

g.addVertex("F")

g.addEdge("A","B");

g.addEdge("A","C");

g.addEdge("B","D");

g.addEdge("B","F");

g.addEdge("D","F");
g.addEdge("D","C");

g.addEdge("F","E");

g.addEdge("F","C");

g.DFSRecursive();

7. Hash_Function

class Hashtable{

constructor(size = 53){

this.keyMap = new Array(size);

_hash(key) {

let total = 0;

let primeNo = 31;

for(let i = 0; i < Math.min(key.length,100); i++){

let char = key[i]

let value = char.charCodeAt(0) - 96;

total = (total * primeNo + value) % this.keyMap.length;

// Debugging line to ensure `total` is within valid range

console.log(`Hash for "${key}":`, total >= 0 ? total : total + this.keyMap.length);

return total >= 0 ? total : total + this.keyMap.length; // Ensure non-negative index

// seperatte chaining

set(key,value){

let index = this._hash(key);


if(!this.keyMap[index]){

this.keyMap[index] = [];

this.keyMap[index].push([key,value]);

get(key){

let index = this._hash(key);

if(this.keyMap[index]){

for(let i = 0; i < this.keyMap[index].length; i++){

if(this.keyMap[index][i][0] === key){

return this.keyMap[index][i][1];

return undefined;

values(){

let valuesArr = [];

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

if(this.keyMap[i]){

for(let j = 0; j < this.keyMap[i].length; j++){

if(!valuesArr.includes(this.keyMap[i][j][1]))

valuesArr.push(this.keyMap[i][j][1])

}
}

return valuesArr;

keys(){

let keysArr = [];

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

if(this.keyMap[i]){

for(let j = 0; j < this.keyMap[i].length; j++){

if(!keysArr.includes(this.keyMap[i][j][0]))

keysArr.push(this.keyMap[i][j][0])

return keysArr;

let hash = new Hashtable(13);

hash.set("Red", "#FF0000");

hash.set("Red", "#FF1111");

hash.set("Green", "#00FF00")

hash.set("Blue", "#0000FF")

hash.set("Yellow", "#FFFF00")

hash.set("Cyan", "#00FFFF")

hash.set("Magenta", "#FF00FF")
hash.set("Orange", "#FFA500")

hash.set("Purple", "#800080");

hash.set("Pur", "#800080");

hash.set("ple", "#800080");

8. Insertion_Sort

function insertionSort(arr) {

for(var i = 1; i < arr.length; i++){

var currentVal = arr[i];

for(var j = i - 1; j >= 0 && arr[j] > currentVal; j--){

arr[j + 1] = arr[j];

arr[j + 1] = currentVal

console.log(arr)

return arr;

insertionSort([21,9,1,76,4])

// [2,1,9,76,4]

// j i

// c

9. Merge_Sort

function merge(arr1,arr2) {

let results = [];


let i = 0;

let j = 0

while(i < arr1.length && j < arr2.length){

if(arr1[i] < arr2[j]){

results.push(arr1[i]);

i++;

} else {

results.push(arr2[j]);

j++

//push remaining elements of arr1 & 2 to the result

while(i < arr1.length){

results.push(arr1[i])

i++

while(j < arr2.length){

results.push(arr2[j])

j++

return results

//time complexity of merge function is O(n + m) where the time

//depends on the size of the n & m which can be arr1 and arr2.

// merge([1,10,50],[2,14,99,100])

// i j

// [1,10,50],[2,14,99,100]
function mergeSort(arr){

if(arr.length <= 1) return arr; //if the elements are divided into a single element in array

let mid = Math.floor( arr.length / 2 );

let left = mergeSort( arr.slice(0,mid) );

let right = mergeSort( arr.slice(mid) );

return merge(left,right)

mergeSort([2,53,235,532,21,53,27,53,86,24,77,91])

// the time complexity of this is O(n log n)

// where the two basic thing mergeSort does is it divides and

// merges them together where the merging time complexity is n

// and the dividing time complexity is log n

// suppose take an example of n = 8 how may times does it split??

// that is log n where log 8 = 3 so it splits 3 times.

// and the merging of the elements is n where all the elements are

// merged together which is n.so dividing(log n),merging (n),so the

// time complexity is O(n log n) for all best, worst, avg

10. Min_Heap_PriorityQ

class Node{

constructor(val, priority){

this.value = val;
this.priority = priority;

class priorityQ {

constructor() {

this.values = [];

enqueue(val, priority) {

let newNode = new Node(val, priority)

this.values.push(newNode);

this.bubbleUp();

bubbleUp(){

let idx = this.values.length - 1;

const element = this.values[idx];

while(idx > 0){

let parentIdx = Math.floor((idx - 1) / 2);

let parent = this.values[parentIdx];

if(element.priority >= parent.priority) break;

// Swap parent and element

this.values[parentIdx] = element;

this.values[idx] = parent;
// Update idx to parent index

idx = parentIdx;

dequeue(){

const min = this.values[0];

const end = this.values.pop();

if(this.values.length > 0){

this.values[0] = end;

this.sinkDown();

return min;

sinkDown(){

let idx = 0;

const length = this.values.length;

const element = this.values[0];

while(true){

let leftChildIdx = 2 * idx + 1;

let rightChildIdx = 2 * idx + 2;

let rightchild,leftchild;

let swap = null;

if(leftChildIdx < length){

leftchild = this.values[leftChildIdx];
if(leftchild.priority < element.priority){

swap = leftChildIdx;

if(rightChildIdx < length){

rightchild = this.values[rightChildIdx];

if(

(swap === null && rightchild.priority < element.priority) ||

(swap !== null && rightchild.priority < leftchild.priority) ){

swap = rightChildIdx;

if(swap === null) break;

this.values[idx] = this.values[swap];

this.values[swap] = element;

idx = swap;

let er = new priorityQ();

er.enqueue("commom cold",5);

er.enqueue("high fever",4);

er.enqueue("gunshot",1);

er.enqueue("broken arm",2);
er.enqueue("allergic reaction",3);

11. Queue_SLL

class Node{

constructor(val){

this.value = val;

this.next = null;

class Queue {

constructor(){

this.first = null;

this.last = null;

this.size = 0;

enqueue(value){ // adding to the end

var newNode = new Node(value);

var current = this.last;

if(!this.first){

this.first = newNode;

this.last = newNode;

}else{

current.next = newNode;

this.last = newNode;
}

return ++this.size;

dequeue(){

if(this.size === 0) return null;

var removedNode = this.first;

if(this.first === this.last){

this.first = null;

this.last = null;

}else{

this.first = removedNode.next;

removedNode.next = null;

this.size--;

return removedNode.value;

show(){

if(!this.first) return null;

var current = this.first;

var values = [];

while(current){

values.push(current.value)
current = current.next;

} console.log(values);

var q = new Queue();

12. Quick_Sort

function pivot(arr,start = 0,end = arr.length+1){

let currPiv = arr[start];

let swapIdx = start;

for(var i= start + 1; i<arr.length; i++){

if(currPiv > arr[i]){

console.log(arr)

swapIdx++;

swap(arr,swapIdx,i);

console.log(arr,"swapped")

swap(arr,start,swapIdx);

return swapIdx;

// this function returns a index which the element is supposed to be in the right place.

// pivot([4,8,2,1,5,7,6,3])

function quickSort(arr,left = 0,right = arr.length - 1) {


if(left < right){

// Get the pivot index after partitioning

let pivotIndex = pivot(arr, left, right)

// Recursively sort left and right parts

// left

quickSort(arr, left, pivotIndex - 1);

// right

quickSort(arr, pivotIndex + 1, right);

return arr;

// for best and avg the time complexity is O(n log n) where the dividing the left and right of the

// pivot is based on the n and it divides upto (log n) and the comparison of the pivot is done to all the

// n elements so the time complexity of that is n combining of these is O(n log n)

// for worst case if the pivot is the first or the last element and for a sorted array we have n
decomposition

// and n comparisons per decomposition so it is O(n2) for worst case.

// to avoid that pick a random or a mid element as the pivot

function swap(array, i, j) {

var temp = array[i];

array[i] = array[j];

array[j] = temp;

//choosing pivot as the median


function medianPivot(arr, start = 0, end = arr.length - 1){

let middle = Math.floor((start + end) / 2)

let first = arr[start];

let last = arr[end];

let mid = arr[middle];

// Finding the median of the three

let piovtIdx = start;

if((first > mid && first < last) || (first < mid && first > last)){

piovtIdx = start;

} else if((mid > first && mid > last) || (mid < start && mid > last)){

pivotIdx = middle;

} else {

pivotIdx = end;

// Swap the median element to the start (so the pivot is at start)

swap(arr,start,piovtIdx);

let currPiv = arr[start];

let swapIdx = start;

for(var i = start + 1; i <= end; i++){

if(arr[i] < currPiv){

swapIdx++;

swap(arr,swapIdx,i);

}
swap(arr,start,swapIdx);

return swapIdx

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,-1];

let startTime = performance.now();

quickSort(arr);

let endTime = performance.now();

console.log(`time taken is ${(endTime - startTime) / 1000} seconds`)

// 0.00020000000298023223 seconds where median is selected and put to start as pivot function:
(medianPivot)

// 0.0019000000022351743 seconds where selecting first as pivot function:(pivot)

// for input [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,-1]

13. Radix_Sort

// helper1

function getDigit(num,i){

return Math.floor(Math.abs(num) / Math.pow(10,i)) % 10;

// getDigit(4,0)

// for this example getDigit(-21434,4)

// Math.abs(-21434)

// 21434
// 21434 / 10000

// 2.1434

// 2.1434 % 10

// 2.1434

// Math.floor(2.1434)

// 2

//this is how it works for this example getDigit(-21434,7)

// Math.abs(-21434)

// 21434

// Math.pow(10, 7)

// 10000000

// 21434 / 10000000

// 0.0021434

// 0.002143 % 10

// 0.002143

// Math.floor(0.002143)

// 0

// helper2

function digitCount(number){

if(number === 0) return 1

return Math.floor(Math.log10(Math.abs(number))) + 1;

// digitCount(9)

// Math.log10(238)

// 2.376576957056512
// Math.log10(2385)

// 3.3774883833761327

// Math.log10(23857)

// 4.3776158305597805

// Math.floor(4.3776158305597805)

// 4

// Math.floor(4.3776158305597805)+1

// 5

// Math.log10(99999) + 1

// 5.999995657033466

// helper 3

function max_digit_of_arr(arr){

let maxDigit = 0;

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

maxDigit = Math.max(maxDigit,digitCount(arr[i]));

return maxDigit;

function radixSort(arr){

let timesToSort = max_digit_of_arr(arr);

console.log("sorting this many times",timesToSort)

for(let k = 0; k < timesToSort; k++){

let digitBuckets = Array.from({length: 10},() => []);

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

let digit = getDigit(arr[i],k);


digitBuckets[digit].push(arr[i])

console.log(digitBuckets)

// [].concat([[1],[2],[3]])

// [Array(1), Array(1), Array(1)] we dont want this all the 0 to 9 in seperate array

// [].concat(...[[1],[2],[3]]) we want them all combined in a single array, so we do the spread ...
operateor

// [1, 2, 3]

arr = [].concat(...digitBuckets);

console.log(arr)

return arr;

let arr = [4321, 984, 7865, 35, 6, 1523, 457, 3219, 678, 97996];

radixSort(arr);

14. Selection_Sort

function selectionSort(arr){

for(var i = 0; i < arr.length; i++){

var lowest = i;

for(var j = i + 1; j < arr.length; j++){

if(arr[j] < arr[lowest]){

lowest = j;

}
console.log(arr[i],arr[lowest])

if(i !== lowest){

console.log("index",i,lowest,"swapping")

var temp = arr[i];

arr[i] = arr[lowest];

arr[lowest] = temp;

console.log(arr);

console.log("***********");

return arr;

selectionSort([0,2,34,22,10,19,17])

// selectionSort([34,28,15,2,8,17,3,5]) // normal unsorted ex

// [34,28,15,2,8,17,3,5]

// i j

// l

// we can also use the other swap swap(arr,i,lowest) const swap = (arr,idx1,idx2) =>

// ([arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]])

//time complexity O(n2)

// in selection sort we only swap once through 1 iteration but in bubble sort we

// swap constantly if the number is greater then the number after it until the

// end gets the highest number.we swap only once in selection and get the smallest to first

// we can choose selection if we want a less write in memory

15. Singly_Linked_List
// piece of data = val

// reference to next node = next

class Node{

constructor(val){

this.val = val;

this.next = null;

class SinglyLinkedList {

constructor(){

this.head = null;

this.tail = null;

this.length = 0;

push(val){ //insert at last

var newNode = new Node(val);

if(!this.head) { // If the list is empty

this.head = newNode;

this.tail = newNode;

} else {

this.tail.next = newNode; // Link the old tail to the new node

this.tail = newNode; // Update the tail to the new node

this.length++;

return this;
}

pop(){ //remove at last

if(this.length === 0) return "empty";

let currentNode = this.head;

let previousNode = null;

while(currentNode.next){ // for(let i = 0; i < this.length - 1; i++)

previousNode = currentNode;

currentNode = currentNode.next;

if(previousNode){

previousNode.next = null; // Detach the last node

this.tail = previousNode; // Update tail to the previous node

} else {

this.head = null;

this.tail = null;

this.length--;

return currentNode.val; // Return the value of the removed node

shift(){ //remove at first

if(!this.head) return "empty";

var temp = this.head;


this.head = this.head.next;

this.length--;

if(!this.head){

this.tail = null;

return temp.val;

unshift(val){

var newNode = new Node(val);

if(!this.head) {

this.head = newNode;

this.tail = newNode;

} else{

newNode.next = this.head;

this.head = newNode;

this.length++;

return this;

get(index){

if(index < 0 || index >= this.length) return null;

let counter = 0;

let current = this.head;

// for(let i = 0; i < index; i++){


// current = current.next;

// }

while(counter !== index){

current = current.next;

counter++;

return current;

set(index,val){

var foundNode = this.get(index);

if(foundNode){

foundNode.val = val;

return true;

return false;

insert(index,val){

if(index < 0 || index > this.length) return false;

var newNode = new Node(val);

if(index === this.length)return !!this.push(newNode);

if (index === 0) return !!this.unshift(newNode);

var previous = this.get(index-1);


var temp = previous.next;

previous.next = newNode;

newNode.next = temp;

this.length++

return true;

remove(index){

if(index < 0 || index >= this.length) return null;

if(index === 0) return this.shift();

if(index === this.length - 1) return this.pop();

var previousNode = this.get(index - 1);

var removedNode = previousNode.next;

previousNode.next = removedNode.next;

this.length--;

return removedNode.val;

reverse(){

if(!this.head) return null; //if list is empty

if(this.length === 1) return this.head.val; //if list has 1 element

var current = this.head;

var next = null;


this.head = this.tail;

this.tail = current;

var previous = null;

var next;

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

next = current.next;

current.next = previous;

previous = current;

current = next;

return this;

find(value){

if(!this.head) return null;

var current = this.head;

var position = 0;

while(current){

if(current.val === value){

return position + 1;

current = current .next;

position++;

return -1;

show(){
if(!this.head) return null;

var current = this.head;

var values = [];

while(current){

values.push(current.val)

current = current.next;

console.log(values);

// var first = new node("hi")

// first.next = new node("how")

// first.next.next = new node("are")

var list = new SinglyLinkedList();

// list.push(65)

// list.push(75)

// list.push(85)

// list.push(62)

// list.unshift(100)

16. Stack_Singly_Linked_List

class Node{

constructor(value){
this.value = value;

this.next = null;

class Stack_SinglyLinkedList{

constructor(){

this.first = null;

this.last = null;

this.size = 0;

push(val){

var newNode = new Node(val);

var current;

if(!this.first){

this.first = newNode;

this.last = newNode;

} else{

current = this.first;

newNode.next = current;

this.first = newNode;

this.size++;

return this.size;

pop(){

if(this.size === 0) return null;


var temp = this.first;

if(this.first === this.last){

this.first = null, this.last = null;

} else{

this.first = temp.next;

temp.next = null;

this.size--;

return temp.value;

var stack = new Stack_SinglyLinkedList();

17. Add

function addUpTo(n) {

let total = 0

for (let i = 0; i <= n; i++) {

total += i;

return total;

//insted of this loop which is O(n) we use a derived formula n*(n+1)/2;

//which is O(1)

var t1 = performance.now();

addUpTo(1000000000);
var t2 = performance.now();

console.log(`Time elapsed:${(t2 - t1) / 1000} seconds.`)

18. Alpha_Numeric

function charCount(str){

let obj = {};

for(let char of str){

if(isAlphaNumeric(char)){ ///[a-zA-Z0-9]/.test(char) so this regular expression works but it is much


slower in different environments

char = char.toLowerCase()

// if(obj[char]){

// obj[char] +=1;

// } else{

// obj[char] = 1;

// } instead of all this we can refactor to

obj[char] = ++obj[char] || 1; //if a char is not in obj yet then

//++obj[char] will be 1 (since undefined is treated as 0 and ++0 results in 1).

//obj[char] = 1 || 1 results in obj['a'] = 1.

return obj;

charCount("hello !!")

// charCount("kjhsdghg 942352&^*#$)(#$##")

//so we use a charCodeAt which returns the Unicode value of a character

//This method returns an integer between 0 and 65535, representing the UTF-16

//code unit of the character at the specified index.


// isAlphaNumeric function instead of the regular expression because of some of its holdbacks,and
disadvantages

function isAlphaNumeric(char){

let code = char.charCodeAt(0);

//here checks if the char is not in the range of alphaNumeric if it isnt it is a different or other
characters

if(!(code > 47 && code < 58) && //numeric (0-9)

!(code > 64 && code < 91) && // upper alpha(A-Z)

!(code > 96 && code < 123)){ // lower alpha(a-z)

return false;

//if it is a alphanumeric it returns true

return true;

// isAlphaNumeric("!") example of the working of isAlphaNumeric returns false

19. Binary_Search

function binary_search(arr, target) {

let left = 0;

let right = arr.length - 1;

while (left <= right) {

let mid = Math.floor((left + right) / 2);

if (arr[mid] === target)

return mid;
else if (arr[mid] < target) {

left = mid + 1;

} else {

right = mid - 1;

return -1;

binary_search([1, 2, 4, 5, 6, 12, 21, 28, 32, 37, 43, 44, 54, 120], 41)

20. Count_Unique_Values

function countUniqueValues(arr){

if(arr.length === 0) return 0

let i = 0;

for(let j=1; j<arr.length; j++){

if(arr[i] !== arr[j]){

i++;

arr[i] = arr[j];

console.log(`the unique values are ${i+1}`);

console.log(arr)

return i+1

}
countUniqueValues([4,4,5,46,,76,57,5,46,34]);

21. Fibonacchi

function fib(n) {

return (n === 0) ? 0 : (n === 1 || n === 2) ? 1 : fib(n - 1) + fib(n - 2)

function fibDP(n, memo = []) {

if(memo[n] !== undefined) return memo[n];

if(n <= 2) return 1;

let res = fibDP(n - 1,memo) + fibDP(n - 2, memo);

memo[n] = res;

return res;

22. Find_Longest_Substring_Sliding_Window

// Sliding Window - findLongestSubstring

// Write a function called findLongestSubstring, which accepts a string and

//returns the length of the longest substring with all distinct characters.

// findLongestSubstring('') // 0

// findLongestSubstring('rithmschool') // 7

// findLongestSubstring('thisisawesome') // 6

// findLongestSubstring('thecatinthehat') // 7

// findLongestSubstring('bbbbbb') // 1

// findLongestSubstring('longestsubstring') // 8
// findLongestSubstring('thisishowwedoit') // 6

// Time Complexity - O(n)

function findLongestSubstring(str) {

let maxLen = 0;

let left = 0;

let charSet = new Set(); // To store unique characters

for(let right=0; right<str.length; right++){

// If character already in set, shrink the window from the left

while(charSet.has(str[right])){

charSet.delete(str[left])

left++;

// Add the new character to the set

charSet.add(str[right]);

// Update maxLength

maxLen = Math.max(maxLen,(right - left) + 1);

return maxLen;

findLongestSubstring('thecatinthehat') // 7

// findLongestSubstring("bbbbbbbbc")

Java_Script_Sort

// A function that determines the order of the elements. The function is called with the

// following arguments:

// a The first element for comparison. Will never be undefined.


// b The second element for comparison. Will never be undefined.

// It should return a number where:

// A negative value indicates that a should come before b.

// A positive value indicates that a should come after b.

// Zero or NaN indicates that a and b are considered equal.

// To memorize this, remember that (a, b) => a - b sorts numbers in ascending order.

function numberCompare(num1,num2){

return num2 - num1;

// num1 - num2; output [2, 4, 10, 15] ascending negative value a should come before b.

// num2 - num1; output [15, 10, 4, 2] descending positive value a should come after b.

// Zero or NaN indicates that a and b are considered equal.

//same for alphabets

[4,2,15,10].sort(numberCompare)

function compareByLen(str1,str2) {

return str2.length - str1.length;

//this sorts by length

// str1.length - str2.length; str1 comes before str2

// output: ['DSA', 'colt', 'keys', 'steele', 'hypocrisy']

// str2.length - str1.length; str1 comes after str2

// output: ['hypocrisy', 'steele', 'colt', 'keys', 'DSA']

["steele","colt","keys","hypocrisy","DSA"].sort(compareByLen)
23. Max_SubArray_Sum

function maxSubarr_sum(arr,target) {

if(target > arr.length) return 0;

var max = -Infinity;

for(let i=0; i <= arr.length - target ; i++){ //if target is 3 8-3=5 it runs upto the index 5.

var temp = 0;

for(let j=0; j<target; j++){

temp += arr[i + j];

if(temp > max){

max = temp;

return max;

maxSubarr_sum([1,2,3,8,5,4,7,2],3)

//here is how it works

//first iteration i=0 upto arr.length-target j upto target

//outer loop i=0 inner loop j=0 to 2

//arr[i+j] which is in first iteration 0+0=0 element = 1 arr[0]=1

//next 0+1 =1 element in 1 is 2 arr[1] = 2

//[0+2] =2 arr[2]=3 temp = 1+2+3 like that it works

//this is O(n^2)

//so we use sliding window which helps to optimize solutions that involve
//traversing or analyzing subarrays of a fixed or variable size

24. Max_SubArray_refactor_SlideWindow

function maxSubArr_sum_Slidewindow(arr,target) {

let maxSum = 0;

for(let i=0; i<target; i++){

maxSum += arr[i]

let tempSum = maxSum

for(let i=target; i<arr.length;i++){

tempSum = tempSum - arr[i - target] + arr[i];

maxSum = Math.max(tempSum,maxSum)

return maxSum

maxSubArr_sum_Slidewindow([2,6,9,3,1,8,5,6,3],3)

//this slide window is O(n)

// arr([2,6,9,2,1,8,5,6,3],3)

//tempSum is 17 of 2,6,9 elements and now to remove the first element and add the next element
where it looks like 6,9,3 as tempSum

//tempSum = 17 - arr[i=3 - target=3] which gives the arr[3-3=0] = element 2

//after removing the previous first element next add the next element which the start of the i is arr[3]

//tempSum = 17 - arr[i - target] + arr[i] gives the next subarray sum compare the tempSumwith
another value maxSum
25. Min_SubArrayLen_refactor_SlideWindow

function minSubArrayLen(arr,target){

var minLen = Infinity;

var left = 0;

var sum = 0;

for(let right= 0; right<arr.length; right++){

sum +=arr[right];

//shrink the window as long as the sum is greater or = to target

while(sum >= target){

minLen = Math.min(minLen,(right-left)+1);

sum -= arr[left];

left++;

return minLen === Infinity ? 0 : minLen

// minSubArrayLen([2,3,1,2,4,3], 7) 2 -> because [4,3] is the smallest subarray

//problem statement

//Sliding Window - minSubArrayLen

// Write a function called minSubArrayLen which accepts two parameters - an array of positive
integers and a positive integer.

// This function should return the minimal length of a contiguous subarray of which the sum is greater
than or equal to the integer passed to the function. If there isn't one, return 0 instead.

// Examples:

// minSubArrayLen([2,3,1,2,4,3], 7) // 2 -> because [4,3] is the smallest subarray


// minSubArrayLen([2,1,6,5,4], 9) // 2 -> because [5,4] is the smallest subarray

// minSubArrayLen([3,1,7,11,2,9,8,21,62,33,19], 52) // 1 -> because [62] is greater than 52

// minSubArrayLen([1,4,16,22,5,7,8,9,10],39) // 3

// minSubArrayLen([1,4,16,22,5,7,8,9,10],55) // 5

// minSubArrayLen([4, 3, 3, 8, 1, 2, 3], 11) // 2

// minSubArrayLen([1,4,16,22,5,7,8,9,10],95) // 0

// Time Complexity - O(n)

// Space Complexity - O(1)

minSubArrayLen([4, 3, 3, 8, 1, 2, 3], 11) //2

26. Naive_Search

function naive_search(str,substr) {

let counter = 0;

for(let i=0; i <= str.length - substr.length; i++){

let match = true;

// Check if the substring matches the main string starting at index 'i'

for(let j=0; j < substr.length; j++){

console.log(str[i+j], substr[j]);

if(str[i + j] !== substr[j]){

match = false;

console.log("BREAK!!");

break; //to stop execution if mismatch is found

if(j === substr.length-1){

console.log(`found one`)
}

// If a match was found, increment the counter

if(match) counter++;

return counter

naive_search("helloilo","mi");

//01234 i 3+1 j 1

//hello

// lo

27. 0&1_Partation

function partitionZeroAnd1(arr){

let left = 0;

let right = arr.length - 1;

while(left < right){

//moves the left pointer to right ++ until 1 is found and stops there to make a swap with right
pointer

while(left < right && arr[left] === 0){

left++;

//moves the right pointer towards left -- until 0 is found and stops there to make a swap with left
pointer

while(left < right && arr[right] === 1){


right--;

//swaps the elements if pointers have not crossed

if(left < right){

[arr[left], arr[right]] = [arr[right], arr[left]]

return arr;

// array[1,0,1,0,1,0,0,1]

const arr = [1,0,1,0,1,0,0,1,1,1,1,0];

partitionZeroAnd1(arr);

28. Recursion_Helper_Method

function collectOddNum(arr) {

let result = [];

function helper(helperInp) {

if(helperInp.length===0){

return;

if(helperInp[0] % 2 !==0){

result.push(helperInp[0]);

helper(helperInp.slice(1))

}
helper(arr);

return result;

collectOddNum([423,42,12,243,24,5,52,22,1,5,3,4,5,6,]);

//odd using only recursion

function oddRecursion(arr) {

let newArr = [];

if(arr.length === 0) return newArr;

if(arr[0] % 2 !==0){

newArr.push(arr[0]);

newArr = newArr.concat(oddRecursion(arr.slice(1)));

return newArr;

oddRecursion([3,2,5,1,5,3,6,7,3,9,0,543,7648,]);
29. Same_Frequency_Number

function same(arr1,arr2){

if(arr1.length !== arr2.length){

return false

const frequencyCounter = {};

for(const num of arr2){

frequencyCounter[num] = (frequencyCounter[num] || 0) + 1;

console.log(frequencyCounter);

console.log("checking in array1")

for(const num of arr1){

const squared = num ** 2;

if(!frequencyCounter[squared]){

return false;

frequencyCounter[squared]--;

console.log(frequencyCounter)

return true

same([1,2,4,3],[9,16,4,1])
30. Same_Naive

//in this we use 2 for loops which run time will be O(n^2)

// function same(arr1, arr2) {

// if (arr1.length !== arr2.length) {

// return false; // Arrays must be of the same length

// }

// // Create a copy of arr2 to avoid modifying the original array

// let arr2Copy = arr2.slice();

// // Iterate through each element in arr1

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

// let found = false;

// let squared = arr1[i] ** 2;

// // Search for the squared value in arr2Copy

// for (let j = 0; j < arr2Copy.length; j++) {

// if (arr2Copy[j] === squared) {

// // Remove the matched value from arr2Copy

// arr2Copy.splice(j, 1);

// found = true;

// break; // Exit the inner loop as we've found a match

// }

// }

// // If no match was found for arr1[i] squared, return false

// if (!found) {
// return false;

// }

// }

// return true; // All elements matched

// }

//this is also the same where 1 is for loop & the other is

//the indexOf which iterates over the arr1 resulting in O(n^2)

function same(arr1, arr2){

if(arr1.length !== arr2.length){

return false;// Arrays must be of the same length

// Iterate through each element in arr1

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

let correctIndex = arr2.indexOf(arr1[i] ** 2)

if(correctIndex === -1) {

return false;

console.log(arr2);

arr2.splice(correctIndex,1)

return true;

same([1,2,4,3],[9,16,4,1])
31. Sum_Zero_Naive

function sumZero(arr){

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

for(let j=i+1; j<arr.length; j++){

if(arr[i] + arr[j] === 0){

return [arr[i],arr[j]]

return false

console.log(sumZero([-5,-1,0,2,3,4,5]))

//time complexity is O(n^2) because of 2 loops

//suppose i is -5 and j iterates over the remaining array

//if it dosen't sum to 0 then i iterate to next -1 and then

//j iterates over the next remaining array.like this it continues

32. Sum_Zero_Refactor

function sumZero(arr) {

let left = 0;

let right = arr.length - 1;

//loop to continue checking until the left pointer crosses the right pointer

while(left < right){


let sum = arr[left] + arr[right];

if(sum === 0){

return [arr[left],arr[right]];

}//if sum is negative iterate left

else if(sum < 0){

left++;

}//if sum is greater than 0 iterate the right

else{

right--;

return false;

console.log(sumZero([-5,-4,-1,0,2,3]))

You might also like