Skip to content

Instantly share code, notes, and snippets.

@lornawanjiru
Last active April 18, 2022 17:01
Show Gist options
  • Save lornawanjiru/d36b624d4c23d3dbd3df2497e80a8749 to your computer and use it in GitHub Desktop.
Save lornawanjiru/d36b624d4c23d3dbd3df2497e80a8749 to your computer and use it in GitHub Desktop.
Data structure and algorithm notes. I have tackled a number of questions and realized i would forget some algorithms since I don't repeat the questions as much. I made this gist to help me go through the question intensively.
##Longest Substring with At Most K Distinct Characters
var lengthOfLongestSubstringKDistinct = function(s, k) {
//incase the length of the string is the same or less than the distict number then return the length of the string.
if(k >= s.length ){
return s.length;
}
//define an empty hash map variable.
let hmap = {}
let max = 0;
//iterating through the string.
for(let right=0,left=0; right<s.length; right++){
//adding values to the hashmap while or increament its number if already present.
hmap[s[right]] = (hmap[s[right]]||0)+1;
//remove the left index character if the unique characters exceed the distinct values allowed.
while(Object.keys(hmap).length>k){
//if the character value is 0 then delete it but if its not 0 just decrement the value by 1;
if(--hmap[s[left]] === 0){
delete hmap[s[left]]
}
left ++;
}
max = Math.max(max,right-left+1);
}
return max;
};
// In this question i had to find the duplicates in an array and return the result in form of an array.
// There so many ways to go about this question.
// Example input : [4,3,2,7,8,2,3,1]
// output : [2,3]
//nums have a range of 1 , n;
//n being the length
/** Conceptual logic
With that range we realise that the numbers in the array have a range that align with the indexes.
e.g [4] = 7;
[2] = 2;
The only thing that can be different is the fact that we dont have 0 and we have element that is equal to the length with as you know has no index value that matches to is.
e.g [8] = not available since index start from 0 => (nums.length - 1 );
So since you have seen the logic till there. We can then move to the next part.
We know that we can use the indexes to get the duplicate but how.
By negating the values at that particular index.
[4,3,2,7,8,2,3,1]
nums[0] = 4;
we need to negate what is at that index though that procudure will miss nums[8].
so we will have to negate the value of nums[nums[0]-1] = meaning nums[0] = 4; nums[4-1] = nums[3];
negate nums[3] = -7;
and keep doing that till you get that the value has already being negated and then push the value to the res.
After finishing with the loop return the res array and you are done .
Good work!!
TRY CODING ON YOUR OWN WITH THE CONCEPTUAL VIEW IN MIND BEFORE CHECKING THE CODE.
**/
var findDuplicates = function(nums) {
// Define the result array that will be returned as mentioned earlier
let res = [];
//a loop to ensure we have dealt with all the elements in the array.
for(let idx = 0; idx<nums.length; idx++){
//intialize the value variable.
//why i added the Math.abs is cause
//for example [1,2,2,4] if negate nums[2] = -2; if i the go to nums[2] again it will be -2 and there is no index of -2.
let value = Math.abs(nums[idx]);
//remember the case of [8] being not available. This is where we deal with that.
let index = value - 1;
if(nums[index] > 0){
nums[index]*= -1;
}
else{
res.push(value)
}
}
return res;
};
/**
* @param {number[]} nums
* @return {number[]}
nums = [4,3,2,7,8,2,3,1]
output = [5,6]
Keeping in mind that the array has a range of [1,n]
n = nums.length
So the missing number has to be in the range of 1 to the length of the array.
We will use indexes to get the missing numbers.
We will set a varaible value that will store the values of nums[i]
Then we set a variable index that will store the index that we will negate. the index variable will be the value - 1 cause we dont have the index of n.
if the nums[index] is positive it means that that index is not occupied.
hence negate it.
Start new loop for the modified nums array. Check the nums[i] that are positive. Positive one is the answer. Hence push it and return after pushing all the disappeared number.
*/
var findDisappearedNumbers = function(nums) {
let result = []
for(let i=0;i<nums.length; i++){
let value = Math.abs(nums[i]);
let index = value-1;
if(nums[index] > 0){
nums[index] = nums[index] * -1;
}
}
for(let i = 0; i<nums.length; i++){
if(nums[i]>0){
result.push(i+1)
}
}
return result;
};
/*
So in this question i decide to use it to perfect my backtracking technique, Which i dont know if am there yet or not.
So here we are suppose to get leeters combination as they appear on a phone dial tab.
Example: '23'
Output should be: ["ad","ae","af","bd","be","bf","cd","ce","cf"].
So how will we go about it.
Since this is a letter combination problem we will use a recursion.
If you draw a tree you can have a visual of what is going on.
I will add letters going down tree from the first letter in each object key to the left node is going to form a length same as the digits length.
*/
var letterCombinations = function(digits) {
if(!digits.length){
return [];
}
const results = [];
const alpha = {
'2':'abc',
'3':'def',
'4':'ghi',
'5':'jkl',
'6':'mno',
'7':'pqrs',
'8':'tuv',
'9':'wxyz'
}
//dfs recursive helper
const dfs = (i, digits, slate) =>{
if(i == digits.length){
results.push(slate.join(''))
return;
}
//dfs recursive case
let chars = alpha[digits[i]];
for(let char of chars){
slate.push(char);
dfs(i+1, digits, slate)
slate.pop();
}
}
dfs(0, digits,[])
return results;
};
/**
example input [1,2,3]
output : [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
So what is permutation ? Permutation from the above example is a getting the different version of an array.. Or interchanging elements of an array til you cant change them any more.
CONCENPTUAL VIEW:
Let's deal with the base case first:
If the given array is empty (array = []), then the function should return [[]].
If the given array only had one element, then it should return [[array[0]].
Now, that we have our base cases, let's go into our recursion. We know that when the array has more than one element, each element has a number of permutations in which that element is the first element.
So that's why we have the outer for loop:
Now, in order to get the other combinations such as [1,3], [2,3], I used the splice(). However, splice() changes the array reference and object, so you must make a copy. Which is why I did let numsCopy = [...nums].Splice() unlike slice returns the removed elements. Slice returns the selected elements.
Now, we simply recurse on numsCopy after we remove the i-th element and it will return an array with the permutations of numsCopy. Then we just add [nums[i], ...perms[j]] to the sol and return the value.
**/
var permute = function(nums) {
// The empty array that we will return at the end
let results = [];
//Our two base cases
if(nums.length == 1){
return [[nums[0]]]
}
else if (nums.length < 0){
return [[]];
}
//loop through the numbers if the nums array has more than one number.
for(let i = 0; i<nums.length; i++){
//Making a copy using the spread operator
let numsCopy = [...nums];
//The splice as mentioned above alters the array and returns the removed elements thats why i copied the array.
numsCopy.splice(i,1);
//Recursively getting the perms.
let perms = permute(numsCopy);
// After that loop through the perms found and push them to the results array.
for(let j = 0; j<perms.length; j++){
results.push([nums[i], ...perms[j]])
}
}
return results;
};
var productExceptSelf = function(nums) {
let len = nums.length;
let left = Array(len + 1);
let right = Array (len + 1);
let res = Array(len);
right[0] = 1;
left[0] = 1;
for(let i=0; i<len; i++){
left[i + 1] = left [i] * nums[i];
}
for(let j=0; j<len; j++){
right[j + 1] = right [j] * nums[len - 1 - j];
}
for (let k =0; k<len; k++){
res[k] = left[k] *right[len-1-k]
}
return res;
};
/**
* @param {ListNode} head
Example input
1->2->3->4->5
Output:
5->4->3->2->1
So you should reverse the linked list.
If you look at it without changing the numbers in in the list it will look like this when inverted :- 1<-2-<-3<-4<-5
Instead of the next of one being two, It should be inverted and the next of two should be one and one should be end of the list.
But how do we do that : We will add a dummy node or a null node that will help us reverse the entire list by pointing the next on one to it and making 2 to point at one.
* @return {ListNode}
*/
var reverseList = function(head) {
//dummy null node to help us change the .next node
let prev = null;
//If the list is null then nothing to be inverted but if the head is available the loop continues.
while(head){
//definig the next variable as head.next then altering the head.next to prev so that it can change directions.
//follow the pattern keenly as its important.
let next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
};
Worst sort algorithm but knowing the algorithm wont hurt;
So in this sorting algorith we are going to traverse the array a number of times till there is no more swaps.
So we will initiate swap as true and while swap is true in the while first change swap to false so that in it actually doesnt swap then its false and it will be returned as it is.
*/
var sortArray = function(nums) {
let swap = true;
let counter = 0;
while(swap){
swap = false;
for(let i = 0; i<nums.length - counter; i++){
let j = i+1;
if(nums[i]>nums[j]){
[nums[i],nums[j]] = [nums[j],nums[i]];
swap = true;
}
}
counter ++;
}
return nums;
};
/**
Its self explanatory, Square all the array
elements then return a sorted
result incase you have a negative number.
**/
function sortedSquaredArray(array) {
for(let i = 0; i<array.length; i++){
array[i] = array[i]**2;
}
return array.sort((a,b)=> a-b);
}
// Do not edit the line below.
exports.sortedSquaredArray = sortedSquaredArray;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment