Javascript loop time complexity - javascript

When looping an array, people often use a simple method like below.
const array = [1,2,3,4,5];
for (let i = 0; i < array.length; i++) {
console.log(array[i]);
}
My question is if array[i] is O(1) operation or not.
For example, when i is 3, does javascript get the number immediately OR count from 0 to 3 again?

Yes. array[i] is O(1). However you do it N times, which makes the entire loop O(n).

Yes, it is O(1).
Because it takes a single step to access an item of an array via its index, or add/remove an item at the end of an array, the complexity for accessing, pushing, or popping a value in an array is O(1).
ref: here

Should be O(1) you can read it at here
javascript array complexity

Related

What is the time complexity of this recursive solution for removing duplicates?

After I complete a Leetcode question, I always try to also determine the asymptotic time complexity, for practice.
I am now looking at problem 26. Remove Duplicates from Sorted Array:
Given a sorted array nums, remove the duplicates in-place such that
each element appears only once and returns the new length.
Do not allocate extra space for another array, you must do this by
modifying the input array in-place with O(1) extra memory.
Clarification:
Confused why the returned value is an integer but your answer is an
array?
Note that the input array is passed in by reference, which means a
modification to the input array will be known to the caller as well.
Internally you can think of this:
// nums is passed in by reference. (i.e., without making a copy) int
len = removeDuplicates(nums);
// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
print(nums[i]);
}
Example 1:
Input: nums = [1,1,2]
Output: 2, nums = [1,2]
Explanation: Your
function should return length = 2, with the first two elements of nums
being 1 and 2 respectively. It doesn't matter what you leave beyond
the returned length.
My code:
/**
* #param {number[]} nums
* #return {number}
*/
var removeDuplicates = function(nums) {
nums.forEach((num,i) => {
if(nums[i+1] !== null && nums[i+1] == nums[i] ){
nums.splice(i, 1);
console.log(nums)
removeDuplicates(nums)
}
})
return nums.length;
};
For this problem, I got O(log n) from my research. Execution time halves each time it runs. Can someone please verify or determine if I am wrong?
Are all recursive functions inherently O(logn)? Even if there are multiple loops?
For this problem, I got O(log n) from my research. Execution time halves for each time it's run. Can someone please verify or determine if I am wrong?
The execution time does not halve for each run: imagine an extreme case where the input has 100 values and they are all the same. Then at each level of the recursion tree one of those duplicates will be found and removed. Then a deeper recursive call is made. So for every duplicate value there is a level in the recursion tree. So in this extreme case, the recursion tree will have a depth of 99.
Even if you would revise the algorithm, it would not be possible to make it O(log n), as all values in the array need to be read at least once, and that alone already gives it a time complexity of O(n).
Your implementation uses splice which needs to shift all the values that follow the deletion point, so one splice is already O(n), making your algorithm O(n²) (worst case).
Because of the recursion, it also uses O(n) extra space in the worst case (for the call stack).
Are all recursive functions inherently O(logn)?
No. Using recursion does not say anything about the overall time complexity. It could be anything. You typically get O(logn) when you can ignore O(n) (like half) of the current array when making the recursive call. This is for instance the case with a Binary Search algorithm.
Improvement
You can avoid the extra space by not using recursion, but an iterative method. Also, you are not required to actually change the length of the given array, only to return what its new length should be. So you can avoid using splice. Instead, use two indexes in the array: one that runs to the next character that is different, and another, a slower one, to which you copy that new character. When the faster index reaches the end of the input, the slower one indicates the size of the part that has the unique values.
Here is how that looks:
var removeDuplicates = function(nums) {
if (nums.length == 0) return 0;
let len = 1;
for (let j = 1; j < nums.length; j++) {
if (nums[j-1] !== nums[j]) nums[len++] = nums[j];
}
return len;
};

How to manage time complexity while working with array comparision using javascript

I need some help. here I am comparing the array's one value with next value using for loop in JavaScript but for long array its taking too much time. I am explaining my code below.
const data = [1,2,3,4,5....1000]
let compareArr = [];
for (let i=0;i<data.length;i++) {
for(let j=i+1;j<data.length;j++) {
compareArr.push(data[i] & data[j]);
}
}
console.log(compareArr)
Here I am using the bitwise AND operator to compare within values one one array but for small length array its ok but if the array length is more than 100 it its taking too much time so here my concern is in which way I can reduce the time complexity of the execution.

How can I insert a value on every index of array using a loop and slice and/or concat?

I'm currently doing an assignment for school and could really use your help.
I have to declare a function which takes two arguments, x and an array, arr. It has to return an array which contains multiple arrays with x inserted into respectively index 0 in the first array, index 1 in the second array and so on until there's no more numbers in the array. See picture of an example and for clarification of what the final result is expected to look like. It has to work on any given array and the assignment specifies that slice() and concat() would be good to use. example of assignment
function insert_all_positions (x, arr) {
var newArr = [];
for(var i = 0; i < arr.length; i++) {
return(arr.concat(x)); }
};
This just adds the x-value to the end of the array and I have to loop it so the value will be inserted at all indexes. I'm thinking the array.splice() method can be used, I'm just not sure how as I'm not particularly experienced with it. Thank you :)
As Nina already said: the idea of assignments is, that you try something yourself which we can then help you to improve.
Nonetheless, here is one simple way of doing what was required:
function iap(v,arr){
var l=arr.length, ret=[];
for (var i=0;i<=l;i++) ret.push(arr.slice(0,i).concat([v],arr.slice(i,l)));
return ret;
}
console.log(iap(8,[1,2,3]));
Try this
function myFunc(x,arr){
let result =[]
for(let i=0;i<arr.length;i++){
let arrToAdd = [...arr]
arrToAdd[i]=x
result.push(arrToAdd)
}
return result
}
You create a result array that you push your arrays into, then you run a loop that will run the exact number of times as the length of your argument arr. Each iteration of the loop creates a new array that is a copy of arr and then you just change one number in it each time and add the entire array to the result.

Why is shift faster than index access in this JavaScript example?

// Shifting the array and accessing 0
let sum = 0;
while(matrix.length > 0) {
sum += matrix[0][0];
matrix.shift();
}
// direct access
let sum = 0;
for (let i = 0; i < matrix.length; i++) {
sum += matrix[i][0];
}
https://jsperf.com/shift-vs-index-access
Shifting the array and accessing 0 is faster than
direct access in the given examples in the above jsPerf link.
Isn't shift() an O(n) operation?
No, it's not faster. It's just your benchmark being broken. The shift() operation empties the matrix array, and after the first iteration you are comparing your codes on an empty array.
When you are benchmarking code that mutates your data structure, you need to re-create the data structure on every test run. I've fixed your jsperf.com case and as expected shift is slower (notice that probably a large part of the execution time is spent on createMatrix, so in fact it's a lot slower).

Efficient duplicates search algorithm

I need a script to search efficiently all the duplicates in a one-dimensional array.
I tried a naive method :
for(var i=0, ii<arr.length-1; i<ii; i++)
for(var j=i+1, jj<arr.length; j<jj; j++)
if(arr[i] == arr[j])
// remove the duplicate
Very simple but it takes a too long time if the array contains a large set of values. The tables that I use often contain hundreds of thousands of values, so that the number of iterations required for this operation is HUGE !
If someone has an idea !?
Use a LinkedHashSet or OrderedHashSet implementation, it does not allow duplicates and provides expected O(1) on insertion, lookup, and deletion. Since your OP says you want to remove the duplicates, there is no faster way to do this than O(n). In an array of 1,000,000 items max time was 16ms
Create a LinkedHashSet hs
foreach object obj in arr
-- hs.add(obj);
Complexity is expected O(n) with a good hash function.
This code could be the most efficient way you can do it ..!! Which is nothing but the direct implementation of set .
function eliminateDuplicates(arr) {
var i,
len=arr.length,
out=[],
obj={};
for (i=0;i<len;i++) {
obj[arr[i]]=0;
}
for (i in obj) {
out.push(i);
}
return out;
}

Categories

Resources