Complexity of two Methods - algorithm

If I have a method that insert an element to an heap with the following code:
(1) If an array is full - create a new array and resize by its original.length * 2 , and then copy each elements from the original array to the new one.
(2). In order to fulfill an Heap just percup/perdown each element to its suit position.
So the worst case complexities are - (1) is O(n) and for (2) its O(logn)
my question is what is the sum of the two complexities? How to calculate the worst case complexity of this algorithm.
Thanks!

For situations like this, if you follow the text book approach the worst case complexity of the algorithm would be
= O(n) + O(logn)
= O(n)
So, the complexity would be O(n)
Actually the name worst case complexity gives you the answer. You should ask yourself the question,
Is there any case where the complexity is O(n).
If yes, then thats the worst case complexity

If you are inserting N elements one by one, then siftUp/siftDown process executes every time, and time dedicated to these procedures is O(NlogN) (as sum of log1+log2+...log(N-1)+log(N))
But array expanding happens seldom. The last expanding takes N steps, previous N/2 steps and so on. Time dedicated to these procedures is
N + N/2 + N/4 + ...+1 = N*(1 + 1/2 +1/4+...) = N*2 = O(N)
So amortized time for expanding part is O(1), and amortized time for inserting part is O(logN)
Overall complexity for N elements is
O(N) + O(NlogN) = O(NlogN)
or
O(logN) per element

Related

Complexity for binary search in a non random access structure

Performing binary search on a sorted array has O(logN) complexity where N is the number of elements in the array.
But if we perform binary searches in a sorted (linked) list then what is the complexity?
We are doing logN comparisons of the middle element of the range but to get to the range the complexity is O(N) due to the fact that the list is not a random access structure.
So is the time complexity:
1) logN * O(N) = O(N) treating logN as a constant? or
2) logN*O(N) = O(NlogN) meaning that logN = O(logN) in all cases?
What is correct here? 1 or 2?
The second assumption is correct and first is wrong. Asymptotic analysis deals with growth. If the number of nodes increase, log(n) would also increase. You can't treat it as a constant. For a very basic example, if you had 10 nodes and it took 10 seconds to execute, assuming 100 nodes take 200 seconds to execute seems better more accurate than assuming 100 seconds (by neglecting log(n)).

Describing space complexity of algorithms

I am currently a CS major, and I am practising different algorithmic questions. I make sure I try to analyse time and space complexity for every question.
However, I have a doubt:
If there are two steps (steps which call recursive functions for varying size of OP) in the algorithm, i.e.
int a = findAns(arr1)
int b = findAns(arr2)
return max(a,b);
Would the worst time complexity of this be: O(N1) + O(N2) or simply, O(max(N1,N2)). I ask because at a time, we would be calling the function with only single input array.
While calculating worst case space complexity, if it comes out to be, O(N) + O(logN), since N > logN, would we discard O(logN) or since logN is also dependent on N and say worst space complexity is O(N), we would say, worst case space complexity to be O(N) only.

Quicksort time complexity when it always select the 2nd smallest element as pivot in a sublist

Time complexity of Quicksort when pivot always is the 2nd smallest element in a sublist.
Is it still O(NlogN)?
If i solve the recurrence equation
F(N) = F(N-2) + N
= F(N-2(2)) + 2N -2
= F(N-3(2)) + 3N - (2+1)(2)
= F(N-4(2)) + 4N - (3+2+1)(2)
Which is O(N^2), but I doubt my answer somehow, someone help me with the clarification please?
To start with, the quicksort algorithm has an average time complexity of O(NlogN), but its worst-time complexity is actually O(N^2).
The generic complexity analysis of quicksort depends not just on the devising of the recurrence relations, but also on the value of the variable K in F(N-K) term of your recurrence relation. And according to whether you're calculating best, average and worst case complexities, that value is usually estimated by the probability distribution of having the best, average, or worst element as the pivot, respectively.
If, for instance, you want to compute the best case, then you may think that your pivot always divides the array into two. (i.e. K=N/2) If computing for the worst case, you may think that your pivot is either the largest or the smallest element. (i.e. K=1) For the average case, based on the probability distribution of the indices of the elements, K=N/4 is used. (You may need more about it here) Basically, for the average case, your recurrence relation becomes F(N) = F(N / 4) + F(3 * N / 4) + N, which yields O(NlogN).
Now, the value you assumed for K, namely 2, is just one shy from the worst case scenario. That is why you can not observe the average case performance of O(NlogN) here, and get O(N^2).

Extracting k largest elements

If I have n integers, is it possible to list the k largest elements out of the n values in O(k+logn) time? The closest I've gotten is constructing a max heap and extracting the maximum k times, which takes O(klogn) time. Also thinking about using inorder traversal.
Ways to solve this problem.
Sort the data, then take top k. Sorting takes O(n lg n) and iterating over the top k takes O(k). Total time: O(n lg n + k)
Build a max-heap from the data and remove the top k times. Building the heap is O(n), and the operation to remove the top item is O(lg N) to reheapify. Total time: O(n) + O(k lg n)
Keep a running min-heap of maximum size k. Iterate over all the data, add to the heap, and then take the entirety of the heap. Total time: O(n lg k) + O(k)
Use a selection algorithm to find the k'th largest value. Then iterate over all the data to find all items that are larger than that value.
a. You can find the k'th largest using QuickSelect which has an average running time of O(n) but a worst case of O(n^2). Total average case time: O(n) + O(n) = O(n). Total worst case time: O(n^2) + O(n) = O(n^2).
b. You can also find the k'th largest using the median-of-medians algorithms which has a worst case running time of O(n) but is not in-place. Total time: O(n) + O(n) = O(n).
You can use Divide and Conquer technique for extracting kth element from array.Technique is sometimes called as Quick select because it uses the Idea of Quicksort.
QuickSort, we pick a pivot element, then move the pivot element to its correct position and partition the array around it. The idea is, not to do complete quicksort, but stop at the point where pivot itself is k’th smallest element. Also, not to recur for both left and right sides of pivot, but recur for one of them according to the position of pivot. The worst case time complexity of this method is O(n^2), but it works in O(n) on average.
Constructing a heap takes O(nlogn), and extracting k elements takes O(klogn). If you reached the conclusion that extracting k elements is O(klogn), it means you're not worried about the time it takes to build the heap.
In that case, just sort the list ( O(nlogn) ) and take the k largest element (O(k)).

analyzing time complexity

I have 2 arrays
a of length n
b of length m
Now i want to find all elements that are common to both the arrays
Algorithm:
Build hash map consisting of all elements of A
Now for each element x in B check if the element x is present in hashmap.
Analyzing overall time complexity
for building hashmap O(n)
for second step complexity is O(m)
So the overall is O(m+n). Am i correct?
What is O(m+n) = ?? when m is large or vice versa?
O(m) + O(n) = O(m+n), if you know that m>n then O(m+n)=O(m+m)=O(m).
Note: hashes theoretically don't guarantee O(1) lookup, but practically you can count on it (= it's the average complexity, the expected runtime for a random input).
Also note, that your algo will repeatedly signal duplicated elements of b which are also present in a. If this is a problem you have to store in the hash that you already checked/printed out that element.
Average case time complexity is O(m + n). This is what you should consider if you are doing some implementation, since hash maps would usually not have collisions. O(m+n) = O(max(m, n))
However, if this is an test question, by time complexity, people mean worst case time complexity. Worst case time complexity is O(mn) since each of second steps can take O(n) time in worst case.

Resources