Improving quicksort to sort in linear time? - arrays

Can we sort unsorted array of real numbers in linear time?
This is what I am thinking :
Given an unsorted array of size n :
Find out the sqrt(n)^th element using selection algorithm (call it x): O(n)
Find out the smaller elements than x and larger elements than x and form 2 arrays : O(n)
Sort the two arrays separately: O(sqrt(n)log(sqrt(n))) = O(n) as log(n) < sqrt(n)
So the whole algorithm is O(n)
I know that lower bound is nlog(n). What am I doing wrong?

Related

Complexity of sorting n/logn sequences of an array size n

Given an array in the size of N (the array contains whole numbers), I wish to sort the array but only on lengths of log(n) in the array, so by the end the array will have n/logn sequences (in the size of logn each sequence) that are sorted.
My idea was to use the algorithm of MergeSort which in worst case of time complexity runs O(nlogn).
But since I am only sorting lengths of logn in the array, the time complexity should be O(log(n)*log(log(n))) because I am not in fact going through the entire length of N.
So MergeSort will be preformed in that case n/logn times.
Is it safe to assume that the overall time complexity of this action would be (n/logn)*O(log(n)log(log(n))) => O(nlog(log(n)))?
Your calculation is correct: sorting n / log n chunks of the array of size log n can be done in O(n log(log n)).
However, if your entire array is not that big in the first place (say a few thousand elements max), the log n chunks will be quite small, in which case it is actually more efficient to use insertion sort rather than an algorithm like merge sort or Quicksort.

What is the Time Complexity Of the following code ? I am Confused

array = [1,2,4,5]
sum = 3
def arrfilter2(arr):
for i in arr:
if ((sum-i) in arr):
return True
return False
print(arrfilter2(array))
enter image description here
If the array is not sorted, (sum - i) in arr takes O(n) (n is the length of the array). In the worst case, the loop scans all of the array. Therefore, the time complexity is O(n^2).
By the way, in the best case, it can be resolved in O(1).
If the array is sorted, you can do it better by the binary search technique instead of "in" operator. In that case, the worst case will be O(n log n).
The time complexity is O(n^2) in the worst case.
In Python, if you search an element using in then it scans through the array linearly to find the element.
To compute the Complexity of an algo, in a naive sense, it is O(n^< no of nested loops>). Here you have two nested so it is O(n^2).
you can make it efficient by sorting it first and then using binary search instead of searching linearly using in

Time complexity of one dimensional and two dimensional arrays

Take for example taking input from the user for a one-dimensional array of size n, we know it's time complexity is O(n).
for(i=0;i<n;i=i+1)
{
scanf("%d",&a[i]);
}
Now if the array is two dimensional, the time complexity is O(n^2)
for(i=0;i<n;i=i+1)
{
for(j=0;j<n;j=j+1)
{
scanf("%d",&a[i][j]);
}
}
But even the two dimensional array is saved in the same manner as the one-dimensional array. It is essentially just an increase in size, why is there a difference?
The difference in the time complexity is because of the number of elements you are storing.
For a linear 1D array, you are storing n elements in a linear way, and it is getting stored in a linear way too. So time complexity is O(n)
For a 2D array, lets suppose you are storing m elements, which are actually stored in a linear way only in the memory. But, what you work with are the elements divided into rows (and columns). Now for instance, the size of each row and column is n, then you are reading n*n elements, which is nothing but m elements only (m == n*n). So the complexity is O(m) or O(n^2)
sort of a perceptual issue, since if you have n elements it would be O(n) either way, but if you are measuring based on one of the array dimensions you aren't going to be n^2 unless it is a square matrix (I see that yours is)... so better to think of it as O(h*w) or just 0(n) anyway...

What is the lowest bound for the algorithm?

Let an algorithm which get unsorted array with the size of n. Let a number k<=n. The algorithm prints the k-smallest numbers from 1 to k (ascending). What is the lower bound for the algorithm (for every k)?
Omega(n)
Omega(k*logn)
Omega(n*logk)
Omega(n*logn)
#1,#2 Are both correct.
Now, from my understanding, if we want to find a lower-bound to an algorithm we need to look at the worst-case. If that the case, then obviously the worst-case is when k=n. We know that sorting an array is bounded by Omega(nlogn) so the right answer is #4.
Unfortunately, I am wrong and the right answer is #5.
Why?
It can be done in O(n + klogk).
Run selection algorithm to find the k smallest element - O(n)
Iterate and return the elements lower/equals k - O(n)
Another iteration might be needed in case of the array allows
duplicates, but it is still done in O(n)
Lastly, you need to sort these elements in O(klogk)
It is easy to see this solution is optimal - cannot get better than O(klogk) factor because otherwise for assigning k=n you could sort any array better, and a linear scan at least is a must to find the required elements to be printed.
Lets try with Linear time:
In order to find the k'th smallest element, we have to use "Randomized-Select" which has the average running time of O(n). And use that element as pivot for the quick sort.
Use Quick sort method to split the array[i] <= k and array[i]>k. This would take O(n) time
Take the unsorted left array[i]<=k (which has k elements) and do counting sort, which will obviously take O(k+K)
Finally the print operation will take O(k)
Total time = O(n)+O(k+K)+O(k) = O(n+k+K)
Here, k is the number of elements which are smaller or equal to K

Sorting an array of integers using algorithm with complexity O(n)

I red already that the best sort comparison algorithms have complexity O(nlog(n)). But I'm asked to sort an array of integers(in C) using a sorting algorithm of complexity O(n) given that all the elements in the array are non-negative and less than a constant K. But I have no idea how to use this information in the sorting algorithm. You guys have any idea?
That's a simple one (known as "counting sort" or "histogram sort", a degenerate case of "bucket sort"):
Allocate an array with one slot for each non-negative integer less than k, and zero it. O(k)
Iterate over all elements of the input and count them in our array. O(n)
Iterate over our array and write the elements out in-order. O(n+k)
Thus, O(n+k).
Radix sort gives you O(n log k), not O(n log n) complexity. Since K is a fixed number independent of n, the resultant complexity is O(n * const), I.e. It is linear.
create a new array of size K and just insert each element to the array in it own position..
lets say K=100
create an array of 100 integers - clear it.
and if you have the set {55, 2, 7, 34}.
you just need to the following:
array[55] = 1;
array[2] = 1;
array[7] = 1;
array[34] =1;
And the go over the array from start to end and just print the index of the cells that are == 1
Depends on the kind of complexity. Average case O(n+k): Bucket Sort.
Radix sort should be O(m * n) though. (m being the length of the key used to sort)

Resources