How to increase the speed of the below program? - arrays

I am trying to solve the below question.
You are given an array of n numbers and q queries. For each query you have to print the floor of the expected value(mean) of the subarray from L to R.
First line contains two integers N and Q denoting number of array elements and number of queries.
Next line contains N space seperated integers denoting array elements.
Next Q lines contain two integers L and R(indices of the array).
Print a single integer denoting the answer.*
I have replaced print() with stdout.write() and input() with stdin.readline().
from sys import stdin, stdout
x,y=map(int,stdin.readline().split())
array=[int(x) for x in stdin.readline().split()]
result=[]
sum=0
for i in range(y):
l,r=map(int,stdin.readline().split())
for i in range(l-1,r):
sum = sum + array[i]
result.append(sum//(r-l+1))
sum=0
for i in result:
stdout.write(str(i)+"\n")
The time taken by my code is about 8 secs, to solve the challenge time limit is 1.5 secs

This type of problem is usually pretty simple if you store the sums from 1-i in the ith value of the array, like so:
from sys import stdin, stdout
x,y=map(int,stdin.readline().split())
array=[int(x) for x in stdin.readline().split()]
sums[0] = array[0]
sums = [sum[i-1]+array[i] for i in range(1,len(array))]
result=[]
for i in range(y):
l,r=map(int,stdin.readline().split())
result.append((sums[r-1]-sums[l-1])//(r-l+1))
for i in result:
stdout.write(str(i)+"\n")
By doing presummation it changes the speed of the program from O(N^2) to O(N) which should be much faster.

Remove the append operation. It is a costly operation and is unecessary since you don't reuse the results. Instead, do directily:
for i in range(l-1,r):
sum = sum + array[i]
stdout.write(str(sum//(r-l+1))+"\n")
By doing like this you avoid go through the second loop too.
If you try, please report here the time taken.

Related

what would be the time complexity of this algorithm?

i was wondering what would be the time complexity of this piece of code?
last = 0
ans = 0
array = [1,2,3,3,3,4,5,6]
for number in array:
if number != last then: ans++;
last = number
return ans
im thinking O(n^2) as we look at all the array elements twice, once in executing the for loop and then another time when comparing the two subsequent values, but I am not sure if my guess is correct.
While processing each array element, you just make one comparison, based on which you update ans and last. The complexity of the algorithm stands at O(n), and not O(n^2).
The answer is actually O(1) for this case, and I will explain why after explaining why a similar algorithm would be O(n) and not O(n^2).
Take a look at the following example:
def do_something(array):
for number in array:
if number != last then: ans++;
last = number
return ans
We go through each item in the array once, and do two operations with it.
The rule for time complexity is you take the largest component and remove a factor.
if we actually wanted to calculate the exact number of operaitons, you might try something like:
for number in array:
if number != last then: ans++; # n times
last = number # n times
return ans # 1 time
# total number of instructions = 2 * n + 1
Now, Python is a high level language so some of these operations are actually multiple operations put together, so that instruction count is not accurate. Instead, when discussing complexity we just take the largest contributing term (2 * n) and remove the coefficient to get (n). big-O is used when discussing worst case, so we call this O(n).
I think your confused because the algorithm you provided looks at two numbers at a time. the distinction you need to understand is that your code only "looks at 2 numbers at a time, once for each item in the array". It does not look at every possible pair of numbers in the array. Even if your code looked at half of the number of possible pairs, this would still be O(n^2) because the 1/2 term would be excluded.
Consider this code that does, here is an example of an O(n^2) algorithm.
for n1 in array:
for n2 in array:
print(n1 + n2)
In this example, we are looking at each pair of numbers. How many pairs are there? There are n^2 pairs of numbers. Contrast this with your question, we look at each number individually, and compare with last. How many pairs of number and last are there? At worst, 2 * n, which we call O(n).
I hope this clears up why this would be O(n) and not O(n^2). However, as I said at the beginning of my answer this is actually O(1). This is because the length of the array is specifically 8, and not some arbitrary length n. Every time you execute this code it will take the same amount of time, it doesn't vary with anything and so there is no n. n in my example was the length of the array, but there is no such length term provided in your example.

What's the time complexity of using for loop to iterate 2D array?

In this answer,it said that:
An algorithm is said to run in linear time if its time execution is directly proportional to the input size, i.e. time grows linearly as input size increases.
I have input a 3x3 array.So I need to input 9 numbers.It need 9 times to iterate.
I have input a 4x4 array.So I need to input 16 numbers.It need 16 times to iterate.
........
The execution of iteration is directly proportional to the amount of numbers(or the size).
So I think the time complexity should be O(n).
But another answer said that:
O(n^c): Time complexity of nested loops is equal to the number of times the innermost statement is executed. For example the following sample loops have O(n^2) time complexity
for (int i = 1; i <=n; i += c) {
for (int j = 1; j <=n; j += c) {
// some O(1) expressions
}
}
I feel a little confused.
So I think the question can also be:
What is the mean of n in array?(Does it means the size of the array or the dimension of the array?)What's the time complexity of use for loop to iterate 2D array.
Is it O(n) or O(n^2)?
If the time complexity is O(n^2) due to it have two for loops.
I use this to create a 3x3 array:
a[0,1,2] -> b[0,1,2] -> c[0,1,2]
So I use it to iterate this arrays.It will be O(n),So it will faster than using for loop to iterate the arrays.Why?
PS:I use Google translation to see those answer,so maybe I misunderstand it.
What is the mean of n in array? (Does it means the size of the array or the dimension of the array?)What's the time complexity of use for loop to iterate 2D array. Is it O(n) or O(n^2)?
You are exactly correct. This is a matter of convention. It is important what n denotes in a particular problem.
In case our array is arr[n][n], iteration takes O(n^2) time. In case our array is arr[k][k] and n=k*k is the size of the array, iteration takes O(n) time. There is no contradiction here since we defined n differently in those cases.
Generally, if you only access an array element once, it is said that you have a linear complexity. No matter how you express this with the O notation.
The complexity for the nested for loop is indeed n^2 and not n. n in array there is the size.
Maybe something to think about to help you: Consider if we needed to iterate over two different arrays in a similar manner and the arrays have different sizes of m and n, e.g.
for (int i = 1; i <=n; i += c) {
for (int j = 1; j <=m; j += c) {
// some O(1) expressions
}
}
This would be O(m*n). The case you're asking about is a specialization of this.
For a 4x4 2D array manipulation if your input was only 4 it would be of exponential complexity. If you're input was all 16 numbers then it's linear. It all comes down to what you're passing in.
In your example if n is your input size then the fact you have a nested iteration makes it O(n^2).
First of all for the question to be answered is "what is n ?".
If you have input a 3x3 array.So you need to input 9 numbers.It need 9 times to iterate.
If you have input a 4x4 array.So you need to input 16 numbers.It need 16 times to iterate
Now if n = 3 & 4 for above two cases respectively then time to iterate is proportional to n square. If n = 9 & 16 for the above cases respectively then it is proportional to n.
Now coming to nested loops.
For an array of size [ROW][COL]
for (int r= 0; r < ROW; r++){ //outer loop
for(int c= 0; c<COL; c++){ // inner loop
//process array[r][c]
}
}
For each iteration of outer loop , we have COL iterations of inner loop. Outer loop iterates for ROW number of times , hence time complexity is of the order ROW multiplied by COL.
Hope this helps.

Finding the Average case complexity of an Algorithm

I have an algorithm for Sequential search of an unsorted array:
SequentialSearch(A[0..n-1],K)
i=0
while i < n and A[i] != K do
i = i+1
if i < n then return i
else return -1
Where we have an input array A[0...n-1] and a search key K
I know that the worst case is n, because we would have to search the entire array, hence n items O(n)
I know that the best case is 1, since that would mean the first item we search is the one we want, or the array has all the same items, either way it's O(1)
But I have no idea on how to calculate the average case. The answer my textbook gives is:
= (p/n)[1+2+...+i+...+n] + n(1-p)
is there a general formula I can follow for when I see an algorithm like this one, to calculate it?
PICTURE BELOW
Textbook example
= (p/n)[1+2+...+i+...+n] + n(1-p)
p here is the probability of an search key found in the array, since we have n elements, we have p/n as the probability of finding the key at the particular index within n . We essentially doing weighted average as in each iteration, we weigh in 1 comparison, 2 comparison, and until n comparison. Because we have to take all inputs into account, the second part n(1-p) tells us the probability of input that doesn't exist in the array 1-p. and it takes n as we search through the entire array.
You'd need to consider the input cases, something like equivalence classes of input, which depends on the context of the algorithm. If none of those things are known, then assuming that the input is an array of random integers, the average case would probably be O(n). This is because, roughly, you have no way of proving to a useful extent how often your query will be found in an array of N integer values in the range of ~-32k to ~32k.
More formally, let X be a discrete random variable denoting the number of elements of the array A that are needed to be scanned. There are n elements and since all positions are equally likely for inputs generated randomly, X ~ Uniform(1,n) where X = 1,..,n, given that search key is found in the array (with probability p), otherwise all the elements need to be scanned, with X=n (with probability 1-p).
Hence, P(X=x)=(1/n).p.I{x<n}+((1/n).p+(1-p)).I{x=n} for x = 1,..,n, where I{x=n} is the indicator function and will have value 1 iff x=n otherwise 0.
Average time complexity of the algorithm is the expected time taken to execute the algorithm when the input is an arbitrary sequence. By definition,
The following figure shows how time taken for searching the array changes with n and p.

How do I iterate through matrix elements matlab

I have the task of creating a piece of matlab code that uses the sieve of Eratosthenes to find the list of prime numbers up to N. I have created a loop that finds the non primes and then finds the index value of them in the list of 2 to N. How do I get my program to take these index values element by element and set the corresponding positions in my zero matrix to one?
Also for my assignment I cannot use the in built isprime functions.
My code so far:
function [p,c] = sieve(N)
N = input('Please type an integer greater than 1: ');
a = ones(1,N); %Non-primes are set to 0
for k = 2:N
How does k:k:end work, I'm guessing it adds k until it reaches N.
Thanks
Assuming your matrix of zeros is called "numbersthatareprime" and your prime indices are called "primeindices":
numbersthatareprime(primeindices)=1
That's just a matter of using your array to index into your vector. As such, create a vector of all zeros that is N in length, then assuming you have the list of prime numbers up to N which is called prim, just do:
vec = zeros(1, N);
vec(prim) = 1;
OK
As OP may still be confused, I'll just give a new answer (not dissimilar to my previous wrong one)
x=zeros(100,1);
for i=2:100;
x(2*i:i:end)=1;
end; find(~x)
You just need to go from 2*i rather than i....
You don't really need a matrix. Just a list of values!
X=zeros(10000,1);
for i=2:100
X(i:i:end) = 1
end
Here, the indexing i:i:end means
[2,4,6,8,...] when i==2
[3,6,9,...] when i==3
etc
So it sets all the multiples of 2, then all the multiples of 3 etc., creating your seive.
Note that you only need to go up to sqrt(N).
Then you can just do find(X) to get the primes!

Algorithm complexity in 2D arrays

Let's suppose that I have an array M of n*m elements, so if I want to print its elements I can do something like:
for i=1 to m
for j=1 to n
print m[i,j]
next j
next i
I know that the print instruction is done in constant time, so in this case I would have an algorithm complexity of:
\sum_{i=1}^{m}\sum_{j=1}^{n}c=m.n.c
so I suppose is in the order of O(n)
But what happens if the array has the same number of rows and columns, I suppose the complexity is:
\sum_{i=1}^{n}\sum_{j=1}^{n}c=n.n.c
so it is of order O(n^{2})
are my assumptions correct?
I'm assuming that m and n are variables and not constants. In that case, the runtime of the algorithm should be O(mn), not O(n), since the runtime is directly proportional to the number of elements in the array. You derived this with a summation, but it might be easier to see by just looking at how much work is done per array element. Given this, you're correct that if m = n, the runtime is quadratic on n.
Hope this helps!

Resources