Smallest number in array and its position - javascript

What I am trying to achieve is to find smallest number in array and its initial position. Here's an example what it should do:
temp = new Array();
temp[0] = 43;
temp[1] = 3;
temp[2] = 23;
So in the end I should know number 3 and position 1. I also had a look here: Obtain smallest value from array in Javascript?, but this way does not give me a number position in the array. Any tips, or code snippets are appreciated.

Just loop through the array and look for the lowest number:
var index = 0;
var value = temp[0];
for (var i = 1; i < temp.length; i++) {
if (temp[i] < value) {
value = temp[i];
index = i;
}
}
Now value contains the lowest value, and index contains the lowest index where there is such a value in the array.

One-liner:
alist=[5,6,3,8,2]
idx=alist.indexOf(Math.min.apply(null,alist))

You want to use indexOf
http://www.w3schools.com/jsref/jsref_indexof_array.asp
Using the code that you had before, from the other question:
temp = new Array();
temp[0] = 43;
temp[1] = 3;
temp[2] = 23;
Array.min = function( array ){
return Math.min.apply( Math, array );
};
var value = temp.min;
var key = temp.indexOf(value);

Find the smallest value using Math.min and the spread operator:
var minimumValue = Math.min(...temp);
Then find the index using indexOf:
var minimumValueIndex = temp.indexOf(minimumValue);
I personally prefer the spread operator over apply.

See this answer of "find max" version of this question. It is simple and good. You can use the index to get the element afterward.

You could use reduce, and compare against Infinity.
let minIndex = -1;
arr.reduce((acc, curr, index) => {
if (curr < acc) {
minIndex = index;
return curr;
} else {
return acc;
}
}, Infinity);

Here is a solution using simple recursion. The output is an object containing the index position of the min number and the min number itself
const findMinIndex = (arr, min, minIndex, i) => {
if (arr.length === i) return {minIndex, min};
if (arr[i] < min) {
min = arr[i]
minIndex = i;
}
return findMinIndex(arr, min, minIndex, ++i)
}
const arr = [5, 5, 22, 11, 6, 7, 9, 22];
const minIndex = findMinIndex(arr, arr[0], 0, 0)
console.log(minIndex);

Related

hasPairsWithSum Google Interview Question

I solved this problem by iterating through the array then find the item when the sum equals to array[i] + item returning true otherwise returning false.
My Question is => How I can return the indices of those numbers that add up to sum not just true? Using the same code below:
function hasPairsWithSum(array,sum) {
for (let i = 0; i < array.length; i++) {
if (array.find((item) => {return sum === array[i] + item}
));
return true;
};
return false;
};
console.log(hasPairsWithSum([1,2,4,4],8))
Note: Time complexity must be less than O(n ^ 2).
JavaScript O(n) Solution.
function hasPairsWithSum(array, sum) {
const map = new Map ();
for(let i = 0; i < array.length; i++) {
let currVal = array[i];
if (map.has(currVal)) {
return [map.get(currVal),i]
}
// difference value = sum - current value
let diff = sum - currVal
map.set(diff,i)
}
};
console.log(hasPairsWithSum([2,2,4,4], 8))
Please refer this code.
function hasPairsWithSum(array,sum) {
let result = [];
for (let i = 0; i < array.length; i++) {
if (array.some((item, index) => {return i === index ? false : sum === array[i] + item}))
result.push(i);
};
return result;
};
console.log(hasPairsWithSum([1,2,4,4],8))
console.log(hasPairsWithSum([3,2,4],6))
console.log(hasPairsWithSum([0,4,3,0],0))
O(n) Soln ... using math concept a+b = n then if a is present in our array then need to find b = n - a is present or not ..
def hasPairsWithSum(array,sum):
d = {}
for i in range(len(array)):
if(array[i] in d):
d[array[i]].append(i)
else:
d[array[i]] = [i]
ans = []
for i in range(len(array)):
val = sum - array[i]
if(val in d):
if(d[val][0] == i):
if(len(d[val]) > 1):
ans.append((i,d[val][1]))
break
else:
continue
else:
ans.append((i,d[val][0]))
break
return ans
print(hasPairsWithSum([4, 4, 4, 4], 8))
O(nlogn) soln ....just store the index with elements .. then sort it by their values .. next step run a loop with complexity of O(n) [concept : Two pointers]
def hasPairsWithSum(array,sum):
arr = []
for i in range(len(array)):
arr.append((array[i],i))
arr.sort()
i = 0
j = len(array)-1
ans = []
while(i<j):
tmp_sum = arr[i][0] + arr[j][0]
if(tmp_sum == sum):
ans.append((arr[i][1] , arr[j][1]))
#add your logic if you want to find all possible indexes instead of break
break
elif(tmp_sum < sum):
i = i + 1
elif(tmp_sum > sum):
j = j - 1
return ans
print(hasPairsWithSum([1,2,4,4],8))
note : if you want to find all possible soln then these approaches will not work either add you own logic in while loop or another approach is use binary search with traversal on every element and store the indexes in set (worst case this will be O(n^2) as we have to find all possible values) Eg: [4,4,4,4,4,4] , sum = 8 and you want to print all possible indexes then we end up running it upto n^2 (why? reason: total possible solns. are 5+4+3+2+1 = n*(n-1)/2 ≈ n^2)
You have to iterate over the array elements checking at every iteration for every element of the array (except the last one) all the elements at the right of it like below:
function findIndexes(array, sum) {
const result = [];
for (let i = 0; i < array.length -1; ++i) {
for (let j = i + 1; j < array.length; ++j) {
if ((array[i] + array[j]) === sum) {
result.push([i, j]);
}
}
}
return result;
}
console.log(findIndexes([1, 2, 4, 4], 8));
console.log(findIndexes([3, 2, 4], 6));
Update:
It is possible to obtain a linear O(n) complexity using an auxiliary Map structure associating an integer value as key with as a value the list containing all the indexes of the elements in the array equal to the integer key like below:
function findIndexes(array, sum) {
const map = new Map();
const result = [];
for (let i = 0; i < array.length; ++i) {
const a = array[i];
const b = sum - a;
if (map.has(b)) {
for (const index of map.get(b)) {
result.push([index, i]);
}
}
const l = map.has(a) ? map.get(a) : [];
l.push(i);
map.set(a, l);
}
return result;
}
console.log(findIndexes([1, 2, 4, 4], 8));
console.log(findIndexes([3, 2, 4], 6));
console.log(findIndexes([1, 1, 1], 2));

How to get unique values from a sorted array with time complexity of O(n) or better without altering the original array

I want to count the unique values in a given array without altering the original array but the solution has to be within the time complexity of O(n). so far all of the solutions I've seen, have a time complexity of O(n^2) like here. I can't find the error in my solution's logic. I'm new to Data Structure & Algorithms and would like a simple solution.
MY CODE -
const countUniqueValues = (arr) =>{
if(arr.length === 0){
return console.log(arr.length);
}else if(arr.length === 1){
return console.log(arr.length);
}
const unique = [];
let i = 0;
for( let j = 1; j < arr.length; j++){
if(arr[i] !== arr[j]){
i ++;
unique.push(arr[i]);
}
}
return console.log(unique);
}
//test cases
countUniqueValues([1,1,1,1,1,2]) // 2
countUniqueValues([1,2,3,4,4,4,7,7,12,12,13]) // 7
countUniqueValues([]) // 0
countUniqueValues([-2,-1,-1,0,1]) // 4
Wrong Output -
[ 1 ]
[
2, 3, 4, 4,
4, 7, 7, 12
]
0
[ -1, -1, 0 ]
Turn the array into a Set (O(n)) and count the set's size:
const countUniqueValues = arr => new Set(arr).size;
NB - very important - the arrays must be sorted for this to work:
This should do the trick:
var prevValue = "";
const countUniqueValues = (arr) =>{
if(arr.length === 0){
return console.log(arr.length);
}else if(arr.length === 1){
return console.log(arr.length);
}
prevValue = arr[0];
let i = 1;
for( let j = 1; j < arr.length; ++j){
if(arr[j] != prevValue){
++i;
prevValue = arr[j];
}
}
console.log(i);
return i;
}
const makeUniqueAndCount = arr => {
const uniqueKeysObject = {};
arr.forEach(number => {
uniqueKeysObject[number] = true;
});
return Object.keys(uniqueKeysObject).length;
};
This solution uses objects in javascript. The keys for a javascript object are always unique. You can then use the keys method of the javascript object prototype to turn it into an array to get its length. This solution will work for an unsorted array as well.

Reorder array for desired output

I got an array
var myArray = [5,8,1,4,2,9,3,7,6];
I want the output to be [ 9, 1, 8, 2, 7, 3, 6, 4, 5 ]. I tried the following code:
function firstAndLast(array) {
var arr= [];
array = myArray.sort().reverse();
for(var i = 0; i < array.length; i++){
var firstItem = myArray[i];
var lastItem = myArray[myArray.length - 1];
if(lastItem > firstItem){
arr.push(array[i]);
}}
var display = firstAndLast(myArray);
console.log(display);
Can anyone suggest what am I missing to achieve the targeted result?
What I want to acheive is to arrange the array in even odd indexes where odd indexes contain larger values in descending order and even indexes contain values in ascending order
Your code actually fits your description, except this part:
if(lastItem > firstItem){
arr.push(array[i]);
}
Why don't you just push both items to the array:
if(lastItem > firstItem){
arr.push(firstItem, lastItem);
}
And the lastItem should be dependent on i:
var lastItem = array[array.length - i - 1];
Them you only have to
return arr;
At the end and it should work :)
function firstAndLast(array) {
const result = [];
array = array.sort((a, b) => a - b).reverse();
for(var i = 0; i < array.length; i++){
var firstItem = array[i];
var lastItem = array[array.length - i - 1];
if(lastItem < firstItem){
result.push(firstItem, lastItem);
}
}
return result;
}
var myArray = [5,8,1,4,2,9,3,7,6];
console.log(firstAndLast(myArray));
Now this only omits the value in the middle, which you can easily add like this in the loop:
if(firstItem === lastItem) {
result.push(firstItem);
}
Apparently you want to shuffle the array?
If that is the case the simplest way of doing it is just using this
function shuffle(array) {
var m = array.length, t, i;
// While there remain elements to shuffle…
while (m) {
// Pick a remaining element…
i = Math.floor(Math.random() * m--);
// And swap it with the current element.
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
}
It is Fisher-Yates shuffle.
More on it on the link : https://bost.ocks.org/mike/shuffle/
If that is not the case post a reply to the comment so we can find some new sorting logic!
function firstAndLast(array) { //You're declaring array here but you're using it in line 3 using the same array without, you're pasing myArray in line 12, my sugestion is to declare array inside de function
var arr = [];
array = myArray.sort().reverse();
for(var i = 0; i < array.length; i++) {
var firstItem = myArray[i];
var lastItem = myArray[myArray.length - 1]; //You're always using the last item of your array, if i'm not wrong (or confused) you want decrement the position, right? you have to use myArray.length-i or a new variable to decrement the position
if(lastItem > firstItem)
arr.push(array[i]); //Again, you're using array when you want to use myArray (it is what you're using for the position in line 5 and 6)
}
var display = firstAndLast(myArray);
console.log(display);

reverse array in place

Why won't this function reverseArrayInPlace work? I want to do simply what the function says - reverse the order of elements so that the results end up in the same array arr. I am choosing to do this by using two arrays in the function. So far it just returns the elements back in order...
var arr = ["a","b","c","d","e","f"]
var arr2 = []
var reverseArrayInPlace = function(array){
var arrLength = array.length
for (i = 0; i < arrLength; i++) {
arr2.push(array.pop())
array.push(arr2.shift())
}
}
reverseArrayInPlace(arr)
Here's a simpler way of reversing an array, using an in-place algorithm
function reverse (array) {
var i = 0,
n = array.length,
middle = Math.floor(n / 2),
temp = null;
for (; i < middle; i += 1) {
temp = array[i];
array[i] = array[n - 1 - i];
array[n - 1 - i] = temp;
}
}
You "split" the array in half. Well, not really, you just iterate over the first half. Then, you find the index which is symmetric to the current index relative to the middle, using the formula n - 1 - i, where i is the current index. Then you swap the elements using a temp variable.
The formula is correct, because it will swap:
0 <-> n - 1
1 <-> n - 2
and so on. If the number of elements is odd, the middle position will not be affected.
pop() will remove the last element of the array, and push() will append an item to the end of the array. So you're repeatedly popping and pushing just the last element of the array.
Rather than using push, you can use splice, which lets you insert an item at a specific position in an array:
var reverseArrayInPlace = function (array) {
var arrLength = array.length;
for (i = 0; i < arrLength; i++) {
array.splice(i, 0, array.pop());
}
}
(Note that you don't need the intermediate array to do this. Using an intermediate array isn't actually an in-place reverse. Just pop and insert at the current index.)
Also, interesting comment -- you can skip the last iteration since the first element will always end up in the last position after length - 1 iterations. So you can iterate up to arrLength - 1 times safely.
I'd also like to add that Javascript has a built in reverse() method on arrays. So ["a", "b", "c"].reverse() will yield ["c", "b", "a"].
A truly in-place algorithm will perform a swap up to the middle of the array with the corresponding element on the other side:
var reverseArrayInPlace = function (array) {
var arrLength = array.length;
for (var i = 0; i < arrLength/2; i++) {
var temp = array[i];
array[i] = array[arrLength - 1 - i];
array[arrLength - 1 - i] = temp;
}
}
If you are doing Eloquent Javascript, the exercise clearly states to not use a new array for temporary value storage. The clues in the back of the book present the structure of the solution, which are like Stefan Baiu's answer.
My answer posted here uses less lines than Stefan's since I think it's redundant to store values like array.length in variables inside a function. It also makes it easier to read for us beginners.
function reverseArrayInPlace(array) {
for (var z = 0; z < Math.floor(array.length / 2); z++) {
var temp = array[z];
array[z] = array[array.length-1-z];
array[array.length-1-z] = temp;
}
return array;
}
You are calling the function with arr as parameter, so both arr and array refer to the same array inside the function. That means that the code does the same as:
var arr = ["a","b","c","d","e","f"]
var arr2 = []
var arrLength = arr.length;
for (i = 0; i < arrLength; i++) {
arr2.push(arr.pop())
arr.push(arr2.shift())
}
The first statements get the last item from arr and places it last in arr2. Now you have:
arr = ["a","b","c","d","e"]
arr2 = ["f"]
The second statement gets the first (and only) item from arr2 and puts it last in arr:
arr = ["a","b","c","d","e","f"]
arr2 = []
Now you are back where you started, and the same thing happens for all iterations in the loop. The end result is that nothing has changed.
To use pop and push to place the items reversed in the other array, you can simply move the items until the array is empty:
while (arr.length > 0) {
arr2.push(arr.pop());
}
If you want to move them back (instead of just using the new array), you use shift to get items from the beginning of arr2 and push to put them at the end of arr:
while (arr2.length > 0) {
arr.push(arr2.shift());
}
Doing a reversal in place is not normally done using stack/queue operations, you just swap the items from the beginning with the items from the end. This is a lot faster, and you don't need another array as a buffer:
for (var i = 0, j = arr.length - 1; i < j; i++, j--) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
This swaps the pairs like this:
["a","b","c","d","e"]
| | | |
| +-------+ |
+---------------+
I think you want a simple way to reverse an array. Hope it will help you
var yourArray = ["first", "second", "third", "...", "etc"]
var reverseArray = yourArray.slice().reverse()
console.log(reverseArray)
You will get
["etc", "...", "third", "second", "first"]
With the constraints I had for this assignment, this is the way I figured out how to solve the problem:
var arr = ["a","b","c","d","e","f"]
var arr2 = []
var reverseArrayInPlace = function(array){
var arrLength = array.length
for (i = 0; i < arrLength; i++) {
arr2.push(array.pop())
}
for (i = 0; i < arrLength; i++) {
array[i] = arr2.shift()
}
}
reverseArrayInPlace(arr)
Thank you for all your help!
***** edit ******
For all of you still interested, I rewrote it using some help from this thread and from my own mental devices... which are limited at this point. Here is it:
arr = [1,2,3,4,5,6,7,8,9,10,11,12,13]
arr2 = ["a","b","c","d","e","f"]
arr3 = [1,2,3]
arr4 = [1,2,3,4]
arr5 = [1,2,3,4,5]
var reverseArrayInPlace2 = function(array) {
var arrLength = array.length
var n = arrLength - 1
var i = 0
var middleTop = Math.ceil(arrLength/2)
var middleBottom = Math.floor(arrLength/2)
while (i < Math.floor(arrLength/2)) {
array[-1] = array[i]
array[i] = array[n]
array[n] = array[-1]
// console.log(array)
i++
n--
}
return array
}
console.log(reverseArrayInPlace2(arr))
console.log(reverseArrayInPlace2(arr2))
console.log(reverseArrayInPlace2(arr3))
console.log(reverseArrayInPlace2(arr4))
console.log(reverseArrayInPlace2(arr5))
P.S. what is wrong with changing global variables? What would the alternative be?
Here is my solution with no temp array. Nothing groundbreaking, just shorter version of some proposed solutions.
let array = [1, 2, 3, 4, 5];
for(let i = 0; i<Math.floor((array.length)/2); i++){
var pointer = array[i];
array[i] = array[ (array.length-1) - i];
array[(array.length-1) - i] = pointer;
}
console.log(array);
//[ 5, 4, 3, 2, 1 ]
I know this is a old question, but I came up with an answer I do not see above. It is similar to the approved answer above, but I use array destructuring instead of a temporary variable to swap the elements in the array.
const reverseArrayInPlace = array => {
for (let i = 0; i < array.length / 2; i++) {
[array[i], array[array.length - 1 - i]] = [array[array.length - 1 - i], array[i]]
}
return array
}
const myArray = [1,2,3,4,5,6,7,8,9];
console.log(reverseArrayInPlace(myArray))
This solution uses a shorthand for the while
var arr = ["a","b","c","d","e","f"]
const reverseInPlace = (array) => {
let end = array.length;
while(end--)
array.unshift(array.pop());
return array;
}
reverseInPlace(arr)
function reverseArrayInPlace (arr) {
var tempArr = [];
for (var i = 0; i < arr.length; i++) {
// Temporarily store last element of original array
var holdingPot = arr.pop();
// Add last element into tempArr from the back
tempArr.push(holdingPot);
// Add back value popped off from the front
// to keep the same arr.length
// which ensures we loop thru original arr length
arr.unshift(holdingPot);
}
// Assign arr with tempArr value which is the reversed
// array of the original array
arr = tempArr;
return arr;
}

Arrays - Find missing numbers in a Sequence

I'm trying to find an easy way to loop (iterate) over an array to find all the missing numbers in a sequence, the array will look a bit like the one below.
var numArray = [0189459, 0189460, 0189461, 0189463, 0189465];
For the array above I would need 0189462 and 0189464 logged out.
UPDATE : this is the exact solution I used from Soufiane's answer.
var numArray = [0189459, 0189460, 0189461, 0189463, 0189465];
var mia= [];
for(var i = 1; i < numArray.length; i++)
{
if(numArray[i] - numArray[i-1] != 1)
{
var x = numArray[i] - numArray[i-1];
var j = 1;
while (j<x)
{
mia.push(numArray[i-1]+j);
j++;
}
}
}
alert(mia) // returns [0189462, 0189464]
UPDATE
Here's a neater version using .reduce
var numArray = [0189459, 0189460, 0189461, 0189463, 0189466];
var mia = numArray.reduce(function(acc, cur, ind, arr) {
var diff = cur - arr[ind-1];
if (diff > 1) {
var i = 1;
while (i < diff) {
acc.push(arr[ind-1]+i);
i++;
}
}
return acc;
}, []);
console.log(mia);
If you know that the numbers are sorted and increasing:
for(var i = 1; i < numArray.length; i++) {
if(numArray[i] - numArray[i-1] != 1) {
//Not consecutive sequence, here you can break or do whatever you want
}
}
ES6-Style
var arr = [0189459, 0189460, 0189461, 0189463, 0189465];
var [min,max] = [Math.min(...arr), Math.max(...arr)];
var out = Array.from(Array(max-min),(v,i)=>i+min).filter(i=>!arr.includes(i));
Result: [189462, 189464]
Watch your leading zeroes, they will be dropped when the array is interpreted-
var A= [0189459, 0189460, 0189461, 0189463, 0189465]
(A returns [189459,189460,189461,189463,189465])
function absent(arr){
var mia= [], min= Math.min.apply('',arr), max= Math.max.apply('',arr);
while(min<max){
if(arr.indexOf(++min)== -1) mia.push(min);
}
return mia;
}
var A= [0189459, 0189460, 0189461, 0189463, 0189465];
alert(absent(A))
/* returned value: (Array)
189462,189464
*/
To find a missing number in a sequence, First of all, We need to sort an array. Then we can identify what number is missing. I am providing here full code with some test scenarios. this code will identify only missing positive number, if you pass negative values even then it gives positive number.
function findMissingNumber(inputAr) {
// Sort array
sortArray(inputAr);
// finding missing number here
var result = 0;
if (inputAr[0] > 1 || inputAr[inputAr.length - 1] < 1) {
result = 1;
} else {
for (var i = 0; i < inputAr.length; i++) {
if ((inputAr[i + 1] - inputAr[i]) > 1) {
result = inputAr[i] + 1;
}
}
}
if (!result) {
result = inputAr[inputAr.length - 1] + 1;
}
return result;
}
function sortArray(inputAr) {
var temp;
for (var i = 0; i < inputAr.length; i++) {
for (var j = i + 1; j < inputAr.length; j++) {
if (inputAr[j] < inputAr[i]) {
temp = inputAr[j];
inputAr[j] = inputAr[i];
inputAr[i] = temp;
}
}
}
}
console.log(findMissingNumber([1, 3, 6, 4, 1, 2]));
console.log(findMissingNumber([1, 2, 3]));
console.log(findMissingNumber([85]));
console.log(findMissingNumber([86, 85]));
console.log(findMissingNumber([0, 1000]));
This can now be done easily as a one-liner with the find method:
const arr = [1,2,3,5,6,7,8,9];
return arr.find((x,i) => arr[i+1]-x > 1) + 1
//4
const findMissing = (arr) => {
const min = Math.min(...arr);
const max = Math.max(...arr);
// add missing numbers in the array
let newArr = Array.from(Array(max-min), (v, i) => {
return i + min
});
// compare the full array with the old missing array
let filter = newArr.filter(i => {
return !arr.includes(i)
})
return filter;
};
const findMissing = (numarr) => {
for(let i = 1; i <= numarr.length; i++) {
if(i - numarr[i-1] !== 0) {
console.log('found it', i)
break;
} else if(i === numarr.length) console.log('found it', numarr.length + 1)
}
};
console.log(findMissing([1,2,3,4,5,6,7,8,9,10,11,12,13,14]))
It would be fairly straightforward to sort the array:
numArray.sort();
Then, depending upon what was easiest for you:
You could just traverse the array, catching sequential patterns and checking them as you go.
You could split the array into multiple arrays of sequential numbers and then check each of those separate arrays.
You could reduce the sorted array to an array of pairs where each pair is a start and end sequence and then compare those sequence start/ends to your other data.
function missingNum(nums){
const numberArray = nums.sort((num1, num2)=>{
return num1 - num2;
});
for (let i=0; i < numberArray.length; i++){
if(i !== numberArray[i]){
return i;
}
}
}
console.log(missingNum([0,3,5,8,4,6,1,9,7]))
Please check below code.....
function solution(A) {
var max = Math.max.apply(Math, A);
if(A.indexOf(1)<0) return 1;
var t = (max*(max+1)/2) - A.reduce(function(a,b){return a+b});
return t>0?t:max+1;
}
Try as shown below
// Find the missing number
let numArray = [0189459, 0189460, 0189461, 0189463, 0189468];
let numLen = numArray.length;
let actLen = Number(numArray[numLen-1])-Number(numArray[0]);
let allNumber = [];
for(let i=0; i<=actLen; i++){
allNumber.push(Number(numArray[0])+i);
}
[...allNumber].forEach(ele=>{
if(!numArray.includes(ele)){
console.log('Missing Number -> '+ele);
}
})
I use a recursive function for this.
function findMissing(arr, start, stop) {
var current = start,
next = stop,
collector = new Array();
function parseMissing(a, key) {
if(key+1 == a.length) return;
current = a[key];
next = a[key + 1];
if(next - current !== 1) {
collector.push(current + 1);
// insert current+1 at key+1
a = a.slice( 0, key+1 ).concat( current+1 ).concat( a.slice( key +1 ) );
return parseMissing(a, key+1);
}
return parseMissing(a, key+1);
}
parseMissing(arr, 0);
return collector;
}
Not the best idea if you are looking through a huge set of numbers. FAIR WARNING: recursive functions are resource intensive (pointers and stuff) and this might give you unexpected results if you are working with huge numbers. You can see the jsfiddle. This also assumes you have the array sorted.
Basically, you pass the "findMissing()" function the array you want to use, the starting number and stopping number and let it go from there.
So:
var missingArr = findMissing(sequenceArr, 1, 10);
let missing = [];
let numArray = [3,5,1,8,9,36];
const sortedNumArray = numArray.sort((a, b) => a - b);
sortedNumArray.reduce((acc, current) => {
let next = acc + 1;
if (next !== current) {
for(next; next < current; next++) {
missing.push(next);
}
}
return current;
});
Assuming that there are no duplicates
let numberArray = [];
for (let i = 1; i <= 100; i++) {
numberArray.push(i);
}
let deletedArray = numberArray.splice(30, 1);
let sortedArray = numberArray.sort((a, b) => a - b);
let array = sortedArray;
function findMissingNumber(arr, sizeOfArray) {
total = (sizeOfArray * (sizeOfArray + 1)) / 2;
console.log(total);
for (i = 0; i < arr.length; i++) {
total -= arr[i];
}
return total;
}
console.log(findMissingNumber(array, 100));
Here is the most efficient and simple way to find the missing numbers in the array. There is only one loop and complexity is O(n).
/**
*
* #param {*} item Takes only the sorted array
*/
function getAllMissingNumbers(item) {
let first = 0;
let second = 1;
let currentValue = item[0];
const container = [];
while (first < second && item[second]) {
if ((item[first] + 1) !== item[second]) { // Not in sequence so adds the missing numbers in an array
if ((currentValue + 1) === item[second]) { // Moves the first & second pointer
first = second;
second++;
currentValue = item[first];
} else { // Adds the missing number between two number
container.push(++currentValue);
}
} else { // Numbers are in sequence so just moves the first & second pointer
first = second;
second++;
currentValue = item[first];
}
}
return container;
}
console.log(getAllMissingNumbers([0189459, 0189460, 0189461, 0189463, 0189465].sort( (a, b) => a - b )));
console.log(getAllMissingNumbers([-5,2,3,9]));
Adding one more similar method
Find the min and max of the numbers in the array
Loop with the max and min numbers to get the full list
compare the full list of numbers with the input array to get the difference
const array = [0189459, 0189460, 0189461, 0189463, 0189465]
const max = Math.max(...array)
const min = Math.min(...array)
let wholeNumber = []
for(var i = min ;i<=max ;i++ ){
wholeNumber.push(i)
}
const missing = wholeNumber.filter((v)=>!array.includes(v))
console.log('wholeNumber',wholeNumber)
console.log('missingNumber',missing)
Here's a variant of #Mark Walters's function which adds the ability to specify a lower boundary for your sequence, for example if you know that your sequence should always begin at 0189455, or some other number like 1.
It should also be possible to adjust this code to check for an upper boundary, but at the moment it can only look for lower boundaries.
//Our first example array.
var numArray = [0189459, 0189460, 0189461, 0189463, 0189465];
//For this array the lowerBoundary will be 0189455
var numArrayLowerBoundary = 0189455;
//Our second example array.
var simpleArray = [3, 5, 6, 7, 8, 10, 11, 13];
//For this Array the lower boundary will be 1
var simpleArrayLowerBoundary = 1;
//Build a html string so we can show our results nicely in a div
var html = "numArray = [0189459, 0189460, 0189461, 0189463, 0189465]<br>"
html += "Its lowerBoundary is \"0189455\"<br>"
html += "The following numbers are missing from the numArray:<br>"
html += findMissingNumbers(numArray, numArrayLowerBoundary);
html += "<br><br>"
html += "simpleArray = [3, 5, 6, 7, 8, 10, 11, 13]<br>"
html += "Its lowerBoundary is \"1\".<br>"
html += "The following numbers are missing from the simpleArray:<br>"
html += findMissingNumbers(simpleArray, simpleArrayLowerBoundary);
//Display the results in a div
document.getElementById("log").innerHTML=html;
//This is the function used to find missing numbers!
//Copy/paste this if you just want the function and don't need the demo code.
function findMissingNumbers(arrSequence, lowerBoundary) {
var mia = [];
for (var i = 0; i < arrSequence.length; i++) {
if (i === 0) {
//If the first thing in the array isn't exactly
//equal to the lowerBoundary...
if (arrSequence[i] !== lowerBoundary) {
//Count up from lowerBoundary, incrementing 1
//each time, until we reach the
//value one less than the first thing in the array.
var x = arrSequence[i];
var j = lowerBoundary;
while (j < x) {
mia.push(j); //Add each "missing" number to the array
j++;
}
} //end if
} else {
//If the difference between two array indexes is not
//exactly 1 there are one or more numbers missing from this sequence.
if (arrSequence[i] - arrSequence[i - 1] !== 1) {
//List the missing numbers by adding 1 to the value
//of the previous array index x times.
//x is the size of the "gap" i.e. the number of missing numbers
//in this sequence.
var x = arrSequence[i] - arrSequence[i - 1];
var j = 1;
while (j < x) {
mia.push(arrSequence[i - 1] + j); //Add each "missing" num to the array
j++;
}
} //end if
} //end else
} //end for
//Returns any missing numbers, assuming that lowerBoundary is the
//intended first number in the sequence.
return mia;
}
<div id="log"></div> <!-- Just used to display the demo code -->

Categories

Resources