Skip to content

Instantly share code, notes, and snippets.

@Revivedaniel
Last active February 21, 2023 23:49
Show Gist options
  • Select an option

  • Save Revivedaniel/a3a5f2514f20ef93d4547694883d4122 to your computer and use it in GitHub Desktop.

Select an option

Save Revivedaniel/a3a5f2514f20ef93d4547694883d4122 to your computer and use it in GitHub Desktop.

Same Frequency(int) Algorithm using the Frequency Counter method

Given I have two numbers, I want to know if they not only have the same numbers, but also if they appeare the same amount of times in the numbers.

sameFrequency(num1, num2)

The numbers passed through will always be positive. The numbers passed through will always be whole numbers. There will only ever be two numbers passed through.

Examples

sameFrequency(182,281)          // true
sameFrequency(34,14)            // false
sameFrequency(3589578, 5879385) // true
sameFrequency(22,222)           // false

Let's break it down!

We will use the following example in the breakdown.

sameFrequency(3589578, 5879385);

Just like in other frequency counter algorithms, we will keep track of the values and their frequencies using a lookup variable.
As we loop over the first number, we will add each value to the lookup and add 1 to it's value every time we encounter it.

(3589578, 5879385)
 ^

lookup = {
  '3': 1
}
(3589578, 5879385)
  ^

lookup = {
  '3': 1,
  '5': 1
}
(3589578, 5879385)
   ^

lookup = {
  '3': 1,
  '5': 1,
  '8': 1
}
(3589578, 5879385)
    ^

lookup = {
  '3': 1,
  '5': 1,
  '8': 1,
  '9': 1
}
(3589578, 5879385)
     ^

lookup = {
  '3': 1,
  '5': 2,
  '8': 1,
  '9': 1
}
(3589578, 5879385)
      ^

lookup = {
  '3': 1,
  '5': 2,
  '8': 1,
  '9': 1,
  '7': 1
}
(3589578, 5879385)
       ^

lookup = {
  '3': 1,
  '5': 2,
  '8': 2,
  '9': 1,
  '7': 1
}

Next, let's loop over second number and apply the same logic but into the second lookup.

(3589578, 5879385)
          ^
lookup2 = {
  '5': 1
}
lookup = {
  '3': 1,
  '5': 2,
  '8': 2,
  '9': 1,
  '7': 1
}
(3589578, 5879385)
           ^
lookup2 = {
  '5': 1,
  '8': 1
}
lookup = {
  '3': 1,
  '5': 2,
  '8': 2,
  '9': 1,
  '7': 1
}
(3589578, 5879385)
            ^
lookup2 = {
  '5': 1,
  '8': 1,
  '7': 1
}
lookup = {
  '3': 1,
  '5': 2,
  '8': 2,
  '9': 1,
  '7': 1
}
(3589578, 5879385)
             ^
lookup2 = {
  '5': 1,
  '8': 1,
  '7': 1,
  '9': 1
}
lookup = {
  '3': 1,
  '5': 2,
  '8': 2,
  '9': 1,
  '7': 1
}
(3589578, 5879385)
              ^
lookup2 = {
  '5': 1,
  '8': 1,
  '7': 1,
  '9': 1,
  '3': 1
}
lookup = {
  '3': 1,
  '5': 2,
  '8': 2,
  '9': 1,
  '7': 1
}
(3589578, 5879385)
               ^
lookup2 = {
  '5': 1,
  '8': 2,
  '7': 1,
  '9': 1,
  '3': 1
}
lookup = {
  '3': 1,
  '5': 2,
  '8': 2,
  '9': 1,
  '7': 1
}
(3589578, 5879385)
                ^
lookup2 = {
  '5': 2,
  '8': 2,
  '7': 1,
  '9': 1,
  '3': 1
}
lookup = {
  '3': 1,
  '5': 2,
  '8': 2,
  '9': 1,
  '7': 1
}

We have counted the frequency of all characters in each number.
Now, we need to compare the two lookups to verify they have the same frequencies!

lookup2 = {
  '5': 2, <-- 2
  '8': 2,
  '7': 1,
  '9': 1,
  '3': 1
}
lookup = {
  '3': 1,
  '5': 2, < -- 2
  '8': 2,
  '9': 1,
  '7': 1
}
lookup2 = {
  '5': 2, 
  '8': 2, <-- 2
  '7': 1,
  '9': 1,
  '3': 1
}
lookup = {
  '3': 1,
  '5': 2, 
  '8': 2, < -- 2
  '9': 1,
  '7': 1
}
lookup2 = {
  '5': 2, 
  '8': 2,
  '7': 1, <-- 1
  '9': 1,
  '3': 1
}
lookup = {
  '3': 1,
  '5': 2, 
  '8': 2,
  '9': 1,
  '7': 1 <-- 1
}
lookup2 = {
  '5': 2, 
  '8': 2,
  '7': 1,
  '9': 1, <-- 1
  '3': 1
}
lookup = {
  '3': 1,
  '5': 2, 
  '8': 2,
  '9': 1, <-- 1
  '7': 1
}
lookup2 = {
  '5': 2, 
  '8': 2,
  '7': 1,
  '9': 1, 
  '3': 1 <-- 1
}
lookup = {
  '3': 1, <-- 1
  '5': 2, 
  '8': 2,
  '9': 1,
  '7': 1
}

All the characters have the same frequency!
Again, if the count's were not the same the output would be false but in this case it is true.

Pseudo Code

Let's start by pseudo coding the edge case where the two numbers are the same.

+// if the two values are the same, return true

Next, we'll convert the numbers to strings and define our lookup variables.
We will also return false if the two strings lengths are not the same since they do not contain the same amount of numbers.

// if the two values are the same, return true
+// Turn the numbers into strings and assign them to variables.
+// If the lengths of both the strings do not match, return false.
+// define a lookup variable to track the frequency

Now, we'll loop over the first string.
If the character is in lookup1, add 1 to it's value.
If the character is not in lookup1, add it with a value of 1.

// if the two values are the same, return true
// Turn the numbers into strings and assign them to variables.
// If the lengths of both the strings do not match, return false.
// define a lookup variable to track the frequency
+// loop over the first string
+  // If the number is in the lookup, add one to it
+  // if the number is not in the lookup, add it with a value of 1 

We'll also repeat this step for the second string and lookup2

// if the two values are the same, return true
// Turn the numbers into strings and assign them to variables.
// If the lengths of both the strings do not match, return false.
// define a lookup variable to track the frequency
// loop over the first string
  // If the number is in the lookup, add one to it
  // if the number is not in the lookup, add it with a value of 1 
+// loop over the second number
+  // If the number is not in the frist lookup, return false
+  // If the number is in the second lookup, add 1 to it

Finally, we will loop over the first string to check if each character is in both lookups and with the same value.
We then return true after the loop since this would mean that all the characters have equal frequencies.

// if the two values are the same, return true
// Turn the numbers into strings and assign them to variables.
// If the lengths of both the strings do not match, return false.
// define a lookup variable to track the frequency
// loop over the first string
  // If the number is in the lookup, add one to it
  // if the number is not in the lookup, add it with a value of 1 
// loop over the second number
  // If the number is not in the frist lookup, return false
  // If the number is in the second lookup, add 1 to it
+// loop over the first stringNum 
+  // If the value at lookup1[stringNum1[i]] does not match lookup2[stringNum1[i]], return false
return true;

Let's code!

Starting with the edge case where the two numbers are the same, we can write an if statement to check the equality.

function sameFrequency(num1, num2){
 // if the two values are the same, return true
 if (num1 === num2) return true;
}

Next, let's turn the numebrs into strings, check the equality of length between the two stringNums, and define our variables.

function sameFrequency(num1, num2){
 if (num1 === num2) return true;
 // Turn the numbers into strings and assign them to variables.
 const stringNum1 = num1.toString();
 const stringNum2 = num2.toString();
 // If the lengths of both the strings do not match, return false.
 if(stringNum1.length !== stringNum2.length) return false;
 // define a lookup variable to track the frequency
 let lookup1 = {};
 let lookup2 = {};
}

Now we will loop over the first string and add an if statement to check if the character exists in the first lookup.
If it does, we will add one to it's value and if not we will add the character to the lookup.

function sameFrequency(num1, num2){
 if (num1 === num2) return true;

 const stringNum1 = num1.toString();
 const stringNum2 = num2.toString();
 if(stringNum1.length !== stringNum2.length) return false;

 let lookup1 = {};
 let lookup2 = {};
 // loop over the first string
 for (let i = 0; i < stringNum1.length; i++) {
   // If the number is in the lookup, add one to it 
   if (lookup1[stringNum1[i]]) {
       lookup1[stringNum1[i]]++
   } else {
     // if the number is not in the lookup, add it with a value of 1 
     lookup1[stringNum1[i]] = 1;
   }
 }
}

We will repeat this logic for the second stringNum and lookup2.
We will also add a piece of logic that will check the first lookup array to see if the character exists.
If it does not, that means we have a character in the second number that did not occur in the first and we should return false.

function sameFrequency(num1, num2){
 if (num1 === num2) return true;

 const stringNum1 = num1.toString();
 const stringNum2 = num2.toString();
 if(stringNum1.length !== stringNum2.length) return false;

 let lookup1 = {};
 let lookup2 = {};
 
 for (let i = 0; i < stringNum1.length; i++) {
   if (lookup1[stringNum1[i]]) {
       lookup1[stringNum1[i]]++
   } else {
     lookup1[stringNum1[i]] = 1;
   }
 }
 
 // loop over the second number,
 for (let i = 0; i < stringNum2.length; i++) {
   // If the number is not in the frist lookup, return false, 
   if (!lookup1[stringNum2[i]]) {
     return false;
   }
   // If the number is in the second lookup, add 1 to it
   if (lookup2[stringNum2[i]]) {
     lookup2[stringNum2[i]]++
   } else {
     // If the number is not in the second lookup, add it equal to 1
     lookup2[stringNum2[i]] = 1;
   }
 }
}

Finally, we will loop over the first string again and check that each character has the same frequency in both lookups.
If the frequency is different between the lookups, we will return false.
Otherwise we will return true after the loop.

function sameFrequency(num1, num2){
 if (num1 === num2) return true;

 const stringNum1 = num1.toString();
 const stringNum2 = num2.toString();
 if(stringNum1.length !== stringNum2.length) return false;

 let lookup1 = {};
 let lookup2 = {};
 
 for (let i = 0; i < stringNum1.length; i++) {
   if (lookup1[stringNum1[i]]) {
       lookup1[stringNum1[i]]++
   } else {
     lookup1[stringNum1[i]] = 1;
   }
 }
 
 for (let i = 0; i < stringNum2.length; i++) {
   if (!lookup1[stringNum2[i]]) {
     return false;
   }
   if (lookup2[stringNum2[i]]) {
     lookup2[stringNum2[i]]++
   } else {
     lookup2[stringNum2[i]] = 1;
   }
 }
 // loop over the first stringNum 
 for (let i = 0; i < stringNum1.length; i++) {
   // If the value at lookup1[stringNum1[i]] do not match lookup2[stringNum1[i]], return false
   if (lookup1[stringNum1[i]] !== lookup2[stringNum1[i]]) return false;
 }


 return true;
}

We now have an algorithm that can tell if two numbers have the same numbers in the same frequency!
Time Complexity - O(N)

Space Complexity - O(1)

function sameFrequency(num1, num2){
 if (num1 === num2) return true;

 const stringNum1 = num1.toString();
 const stringNum2 = num2.toString();
 if(stringNum1.length !== stringNum2.length) return false;

 let lookup1 = {};
 let lookup2 = {};
 
 for (let i = 0; i < stringNum1.length; i++) {
   if (lookup1[stringNum1[i]]) {
       lookup1[stringNum1[i]]++
   } else {
     lookup1[stringNum1[i]] = 1;
   }
 }
 
 for (let i = 0; i < stringNum2.length; i++) {
   if (!lookup1[stringNum2[i]]) {
     return false;
   }
   if (lookup2[stringNum2[i]]) {
     lookup2[stringNum2[i]]++
   } else {
     lookup2[stringNum2[i]] = 1;
   }
 }
 
 for (let i = 0; i < stringNum1.length; i++) {
   if (lookup1[stringNum1[i]] !== lookup2[stringNum1[i]]) return false;
 }

 return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment