find multiple elements of different ranks from unsorted array - algorithm

I am working with very interesting [problem][1]:
Given an unsorted array of n distinct elements, We want to find this set of
logn elements: those at positions 1,2,4,8,16,..., n/2 in the sorted order. (The element at position 1 in the sorted order is the minimum, the one in position 2 is the 2nd smallest, ..., and the one in position n is the largest.)
Assume n is a power of 2 . How fast can you find all these logn elements?
My thought process:
we can find elements of any rank from an array in O(n) using the median of medians. I will not find elements in the order written above which is 1,2,4,8,16,..., n/2. I will first take the middle of asked elements (say k) which is at index (logn)/2 and then i will divide original unsorted array into two parts using two parts using k and i will work on these two parts indiviually. Using this approach i am getting loglogn levels and at each level n amount of work is to be done hence time complexity is nloglogn.
But the options given link does not have this option.
[1](page 2)
https://d1b10bmlvqabco.cloudfront.net/attach/ixj45csz3f961q/grs52ylqx9y/j28yy7bo8jvm/final.pdf

Related

Finding number of length 3 increasing (or decreasing) subsequences?

Given an array of positive integers, how can I find the number of increasing (or decreasing) subsequences of length 3? E.g. [1,6,3,7,5,2,9,4,8] has 24 of these, such as [3,4,8] and [6,7,9].
I've found solutions for length k, but I believe those solutions can be made more efficient since we're only looking at k = 3.
For example, a naive O(n^3) solution can be made faster by looping over elements and counting how many elements to their left are less, and how many to their right are higher, then multiplying these two counts, and adding it to a sum. This is O(n^2), which obviously doesn't translate easily into k > 3.
The solution can be by looping over elements, on every element you can count how many elements to their left and less be using segment tree algorithm which work in O(log(n)), and by this way you can count how many elements to their right and higher, then multiplying these two counts, and adding it to the sum. This is O(n*log(n)).
You can learn more about segment tree algorithm over here:
Segment Tree Tutorial
For each curr element, count how many elements on the left and right have less and greater values.
This curr element can form less[left] * greater[right] + greater[left] * less[right] triplet.
Complexity Considerations
The straightforward approach to count elements on left and right yields a quadratic solution. You might be tempted to use a set or something to count solders in O(log n) time.
You can find a solder rating in a set in O(log n), however, counting elements before and after will still be linear. Unless you implement BST where each node tracks count of left children.
Check the solution here:
https://leetcode.com/problems/count-number-of-teams/discuss/554795/C%2B%2BJava-O(n-*-n)

How can i find the minimum interval that contains half of n numbers?

If I have n numbers , how do I find the minimum interval [a,b] that contains half of those numbers ?
Sort numbers
Set left index to 0, right to n/2-1, get difference A[right]-A[left]
Walk n/2 steps in for-loop, incrementing both indexes, calculating difference again, remember the smallest one and corresponding indexes.
Sort the numbers increasingly and compute all the differences A[i+n/2] - A[i]. The solution is given by the index that minimizes the difference.
Explanation:
There is no need to search among the intervals that contain less than n/2 numbers (because they do not satisfy the conditions) nor those that contain more elements (because if you find a suitable interval, it won't be minimal because you can remove the extreme elements).
When the elements are sorted, any sequence in the array is bounded by its first and last elements. So it suffices to sort the numbers and slide a window of n/2 elements.
Now it is more challenging to tell if this O(n log n) approach is optimal.
How about the following?
Sort the given series of numbers in ascending order.
Start a loop with i from 1st to ([n/2])th number
Calculate the difference d between i + ([n/2])th and ith number. Store the numbers i, i + [n/2] and d in an iteratable collection arr.
End loop
Find the minimum value of d from the array arr. The values of i and i + [n/2] corresponding to this d is your smallest range.

how to find one of the k smallest elements in n-k comparisions given that Array is unsorted and n is the size of the array

You are given two inputs: an integer k, and an array A containing n integers.
Give an algorithm to find any one of the k smallest elements of A, using at most
n − k comparisons. (In other words, your algorithm must return one of the k
smallest elements of A, but it doesn’t matter which one.) Explain why your
algorithm is guaranteed to find a correct answer and why it satisfies the bound
on the running time. (Hint: there is a very easy way to solve this problem).
For k=1 I can find the smallest element in n-1 comparisons - just go along the array and keep track of the smallest element seen so far.
For k=2 find the smallest element of the first n-1 elements in the array, using n-2 comparisons. This is the smallest element in the whole array unless the element you missed is smaller, in which case it is the second smallest, which is OK.
For general k, find the smallest element in the first n-k+1, neglecting the last k-1 elements in the array. The result is the smallest element unless up to k-1 of the remaining elements are smaller, in which case it is still among the k smallest elements, and you are OK.

K'th Min From a set of intervals

You have given a set of intervals like {2,7} , {3,8}, {9,11} , {-4,-1} so on. The question is to find the k'th min from these set of intervals.
Also the duplicates are counted twice. For example if intervals are {1,4} and {2,6} and k = 3 then the answer is 2 because if we flatten the intervals and sort merge them then we get the sequence
1,2,2,3,3,4,4,5,6
Where 3rd min is 3.
There can be a lot of ways to solve this problem. However I am struggling to find the one with minimum time / space complexity.
Flat the intervals.
Sort the flatten sequence.
Iterate over the sorted sequence, until you find the k-th element,
while ignoring duplicate values.
Now let's do some analysis, where we set N the number of total numbers present in your intervals and M the average number of duplicate values a number will have (will be 1 for a unique flatten sequence).
Space Complexity:
O(N)
where you could do better, if you have many duplicate elements, by iterating over the flatten sequence, while discarding the duplicate elements.
Time Complexity:
O(k*M + NlogN)
Flattening takes O(N)
Sorting takes O(NlogN)
Iteration takes O(k*M)

Two sorted array, perform swaps so that each element in the first is smaller than any of the elements in the second

I need to create an algorithm to solve the following problem:
Given two sorted arrays (both have n elements) I need to modify them so that each element in the first array is smaller than any element in the second array. The operations I could do is compare two elements and swap two elements.
My first solutions is this:
Let a be the last element of the first array and let b be the first element of the second array. If a<b then we stop, otherwise we swap them and continue with arrays n-1 smaller (erase last element in the first, the first in the second).
This is obviously linear.
But what if I wanted to minimize the number of comparisons made in this algorithm? In this one I make a linear number of swaps and comparisons. Could I go smaller with comparisons?
I could do a double binary search I think. Meaning I search for such element a' in the first array that is bigger then some element b' in the second array but smaller then the one next to him. This has complexity O(lg n^2). Can I do better?
Your algorithm is not working with O(lg n^2).
With binary search you will decrease the number of comparison from O(n) to log(n), but the number of swap operation will still be O(n)
Yes, your algorithm will be slightly improved but the complexity stays the same. You have to do k number of swaps where 0<=k<=n

Resources