Question about JavaScript Code Time Complexity - javascript

var findDisappearedNumbers = function(nums) {
const numberSet = new Set();
for(let i = 1; i < nums.length + 1; i++) {
numberSet.add(i);
}
nums.forEach((element) => {
if(numberSet.has(element)) {
numberSet.delete(element);
}
});
return Array.from(numberSet);
};
Above is a solution for leetcode problem 448.
https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/description/
Apparently the time complexity of the program is O(n). This is what I dont understand, shouldn't it be O(n^2) since you iterate nums once to populate numberSet, then you iterate over nums again to check duplicates?
So both the for loop and nums.forEach are both O(n) making it overall O(n^2)?

The time complexity is O(N) and not O(n^2) because you iterate the nums twice, which means that the time complexity is O(2N) which you can just simplify into O(N). The time complexity will be O(n^2) if you iterate the nums within an iteration of nums like:
for(let i = 1; i < nums.length + 1; i++) {
for(let j = 1; j < nums.length + 1; j++){
// code
}
}
Hope this helps

Since there are two loops, the time complexity would technically be O(2n). However, with asymptotic analysis, we drop constant coefficients and lesser terms. So O(2n) is equivalent to O(n).
If the loops were nested, the runtime would be O(n^2). For example:
for (let i = 1; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
// Do something
}
}

This solution is easy to understand;
var findDisappearedNumbers = function (nums) {
const numberSet = new Set(nums);
let result = [];
for (let i = 1; i < nums.length + 1; i++) {
if (!numberSet.has(i + 1)) {
result.push(i);
}
}
return result;
};

Related

Find all the Subarrays in O(nlog(n)) time complexity JavaScript

how to get all the subarrays in O(nlog(n)) time complexity using javaScript
I try with a nested loop but the time complexity is in O(n*n). I heard about some prefix solutions but have no information
try this code :
fetechArray = (array) => {
for ( let subarray of array ){
// ur code here
fetechArray(subarray);
}
}
Use the "divide & conquer" approach. You first divide the original array into two halves, then combine the results from both halves to get all subarrays.
function subArrays(arr) {
if (arr.length === 1) {
return [arr];
}
const mid = Math.floor(arr.length / 2);
const left = arr.slice(0, mid);
const right = arr.slice(mid);
const leftSubArrays = subArrays(left);
const rightSubArrays = subArrays(right);
return merge(leftSubArrays, rightSubArrays);
}
function merge(left, right) {
const result = [];
for (let i = 0; i < left.length; i++) {
for (let j = 0; j < right.length; j++) {
result.push(left[i].concat(right[j]));
}
}
return result;
}

Is there an efficient way, besides using a double for loop, to generate a LIST of all possible pairs of indices (i, j) given an array so that i <= j?

Just to note - I don't just want the number of all the possible pairs, I need an actual array/list of all possible indices pairs.
I get that you can use a double for loop or generate combinations but the problem is that the time complexity would be O(N^2) and O(k(N! / [(N-k)! * k!])) where k = 2, respectively. So it makes it difficult to generate all possible pairs of indices if you have a large array of say over 1000 elements.
For example, the following worked when I use small arrays but is there anything more efficient to generate this list of [i, j] indices or an algorithm anyone could point me towards that might give me a solution?
Double for loop:
let pairs = [];
for (let i = 0; i < array.length; i++) {
for (let j = i; j < array.length; j++) {
pairs.push([i, j]);
}
}
Combinations using backtracking:
function findPairs(arr) {
let result = [];
backtrack(0, result, arr.length, [], 2);
for (let i = 0; i < arr.length; i++) {
result.push([i, i]);
}
return result;
}
function backtrack(start, result, len, curr, k = 2) {
if (curr.length === k) result.push([...curr]);
for (let i = start; i < len + 1; i++) {
curr.push(i);
backtrack(i + 1, result, len, curr, 2);
curr.pop()
}
return result;
}

find all numbers disappeared in array

Please help me to solve this leetcode problem using javascript as I am a beginner and dont know why this code is not working
Ques: Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
var findDisappearedNumbers = function (nums) {
var numLength = nums.length;
nums.sort(function (a, b) { return a - b });
for (var i = 0; i < nums.length - 1; i++) {
if (nums[i + 1] === nums[i]) {
nums.splice(i, 1);
}
}
for (var k = 0; k < nums.length; k++) {
for (var j = 1; j <= numLength; j++) {
if (nums[k] !== j) {
return j;
}
}
}
};
if there is any error in my code please let me know;
i have done the following thing
first i have sorted the array in ascending order
then i have cut all the duplicate elements
then i have created loop that will check if nums[k] !== j ;
and it will return j which is the missing number;
for example this is the testcase [4,3,2,7,8,2,3,1]
first my code will sort this in ascending order [1,2,2,3,3,4,7,8]
then it will remove all duplicate elements and it will return [1,2,3,4,,7,8]
and then it will check nums[k] is not equal to j and it will print j
I think it'd be easier to create a Set of numbers from 1 to n, then just iterate through the array and delete every found item from the set:
var findDisappearedNumbers = function(nums) {
const set = new Set();
for (let i = 0; i < nums.length; i++) {
set.add(i + 1);
}
for (const num of nums) {
set.delete(num);
}
return [...set];
};
console.log(findDisappearedNumbers([4,3,2,7,8,2,3,1]));
To fix your existing code, I'm not sure what the logic you're trying to implement in the lower section, but you can iterate from 1 to numLength (in the outer loop, not the inner loop) and check to see if the given number is anywhere in the array. Also, since you're mutating the array with splice while iterating over it in the upper loop, make sure to subtract one from i at the same time so you don't skip an element.
var findDisappearedNumbers = function(nums) {
var numLength = nums.length;
nums.sort(function(a, b) {
return a - b
});
for (var i = 0; i < nums.length - 1; i++) {
if (nums[i + 1] === nums[i]) {
nums.splice(i, 1);
i--;
}
}
const notFound = [];
outer:
for (var j = 1; j < numLength; j++) {
for (var k = 0; k < nums.length; k++) {
if (nums[k] === j) {
continue outer;
}
}
notFound.push(j);
}
return notFound;
};
console.log(findDisappearedNumbers([4, 3, 2, 7, 8, 2, 3, 1]));
#CertainPerformance certainly cracked it again using the modern Set class. Here is a slighly more conservative approach using an old fashioned object:
console.log(missingIn([4,3,2,7,8,2,3,1]));
function missingIn(arr){
const o={};
arr.forEach((n,i)=>o[i+1]=1 );
arr.forEach((n) =>delete o[n] );
return Object.keys(o).map(v=>+v);
}
My solution for the problem to find the missing element
var findDisappearedNumbers = function(nums) {
const map={};
const result=[];
for(let a=0;a<nums.length;a++){
map[nums[a]]=a;
}
for(let b=0;b<nums.length;b++){
if(map[b+1]===undefined){
result.push(b+1)
}
}
return result;
};
Example 1:
Input: nums = [4,3,2,7,8,2,3,1]
Output: [5,6]
Example 2:
Input: nums = [1,1]
Output: [2]

Make an array filled with numbers 1 to 10000 and then sum all of those numbers [duplicate]

This question already has answers here:
How to find the sum of an array of numbers
(59 answers)
Closed 6 years ago.
How can I turn this into a function that takes an array of any length and gives you the total?
var points = new Array(100);
for (var i = 0; i < 100; i++) {
points[i] = i + 1;
}
for(var i = 0; i < points.length; i++) {
console.log(points[i]);
}
You could do it in two loops, but you might as well just do one loop that does both tasks.
var array = [],
sum = 0;
for (var i = 1; i <= 10000; i++) {
array[i-1] = i;
sum += i;
}
If you want to generalize the task of finding the sum of an array, you can use a function like so:
function arraySum(array) {
var sum = 0;
for (var i = 0; i < array.length; i++)
sum += array[i];
return sum;
}
For those who can understand it though, using reduce is a best answer:
function arraySum(array) {
return array.reduce(function(a,b){return a+b}, 0);
}
You can do get the sum using the for loop itself simply by using a variable
var points = new Array(100),
sum = 0;
for (var i = 0; i < 100; i++) {
points[i] = i + 1;
}
for (var i = 0; i < points.length; i++) {
sum += points[i];
}
console.log(sum);
You can reduce these two operations using fill() and forEach() to generate the array and reduce() to get the sum
var points = new Array(10000); // create an array of size 10000
points.fill(1); // fill it with 1 which helps ti=o iterate using foreach
points.forEach(function(v, i) { // iterate the array, you can also use simple for loop here
points[i] = v + i; // update the value
});
var sum = points.reduce(function(a, b) { // find sum
return a + b;
});
console.log(sum);
Using for loop and reduce()
var points = []; // initialize an array
for (var i = 1; i <= 10000; i++) {
points.push(i);
}
var sum = points.reduce(function(a, b) { // find sum
return a + b;
});
console.log(sum);
Also you can do the addition and array creation in single for loop
var points = [], // initialize an array
sum = 0;
for (var i = 1; i <= 10000; i++) {
points.push(i); // pushing value to array
sum += i; // summation
}
console.log(sum, points);
var result = 0;
for(var i = 0; i < points.length; i++) {
result += points[i];
}
Function that takes an array of any length and returns the sum:
function sumArray(arrayToSum){
var result = 0;
for(var i = 0; i < arrayToSum.length; i++) {
result += points[i];
}
return result;
}
function arraysum(arraylength) {
var arraysum = 0;
var array1 = new Array();
for(i=1; i<=arraylength; i++) {
array1.push(i);
}
for(i = 0; i< array1.length; i++) {
arraysum += array1[i];
}
return arraysum;
}
Now when you call the function
arraysum(x)
pass the function some variable or integer for example 1, 15, or 10000.
A very elegant and compact solution is to use reduce. It accumulates the array values to reduce it to a single value by applying each value and a start value to a given function, whose return value is used as the start value for the next iteration:
function sum (a, b) {
return a + b;
}
console.log(points.reduce(sum, 0));
If you need to support older browser (e.g. IE 8) you can use a Polyfill.
If you need to create the list of numbers as well, you can create it with
var points = Array.apply(0, Array(10000))
.map(function (current, index) {
return index + 1;
});
It creates an array of 10000 elements and assigns each element it's index + 1.

Take an input single dimensional array [1,2,3,4] and output the product of the integers excluding the current index [24,12,8,6];

Guys I need your opinion; I've encountered this earlier during my interview, I just want to confirm I understood the question right and I got the answer correctly. Thank you. Please check the question and my answer below:
Take an input single dimensional array [1,2,3,4] and output the product of the integers excluding the current index [24,12,8,6];
//My answer
function calculate(values:Array):Array {
var resultArray:Array = new Array();
for(var i:int = 0; i < values.length; i++) {
var getVal1:Number = 1;
for(var k:int = 0; k <= values.length; k++) {
if(i != k) {
var getVal2:Number = values[k];
getVal1 *= getVal2;
}
}
resultArray.push(getVal1);
}
return resultArray;
}
Nested loops seems like a very messy way to go.
Assuming relatively up-to-date browser (IE 8 and below are out) or suitable shim:
var resultArray = sourceArray.map(function(val,ind,arr) {
arr = arr.slice(0); // create copy of array to work on here
arr.splice(ind,1); // remove current item from array
return arr.reduce(function(prev,curr) {return prev*curr;},1);
});
Array.prototype.map
Array.prototype.reduce
EDIT Here's another way that should be more efficient:
var product = sourceArray.reduce(function(prev,curr) {return prev*curr;},1);
var resultArray = sourceArray.map(function(val) {return product/val;});
Your solution gives the correct answer, but there is a much more efficient method to calculate the new array:
function calculate(values:Array):Array {
var resultArray:Array = new Array();
var product:int = 1;
for(var i:int = 0; i < values.length; i++) {
product *= values[i];
}
for(var i:int = 0; i < values.length; i++) {
resultArray.push(product / values[i]);
}
return resultArray;
}
This solution has O(n) execution time, while your code has O(n²) execution time.
That should work. You can do it easier and more efficiently by multiplying all items first:
function calculate(values) {
var prod = 1;
for (var i = 0; i < values.length; i++) prod *= values[i];
var result = [];
for (i = 0; i < values.length; i++) result.push(prod / values[i]);
return result;
}
I believe that my code below is very easy to read. And has no nested loops, but two consecutives. My answer would be:
function calculate(array){
var total = array.reduce(function(a, b){
return a * b;
});
return array.map(function(element){
return total / element;
});
}
Though I like #Kolink's short-and-efficient solution best, here's another way to solve the task - not using division but still being in O(n):
function calculate(values) {
var acc = 1,
l = values.length,
result = new Array(l);
for (var i=0; i<l; i++) {
result[i] = acc;
acc *= values[i];
}
acc = 1;
while(i--) {
result[i] *= acc;
acc *= values[i]
}
return result;
}
Or, the same thing but a little obfuscated*:
function calculate(values) {
var acc = 1,
i = 0,
l = values.length,
result = new Array(l);
if (l)
result[i] = 1;
while( ++i < l)
result[i] = acc *= values[i-1];
i -= acc = 1;
while (i--)
result[i] *= acc *= values[i+1];
return result;
}
*: I like shorthand operators!

Categories