• retagged by
4,667 views
19 19 votes

Let $S$ be a set of numbers. For $x \in S$, the rank of $x$ is the number of elements in $S$ that are less than or equal to $x$. The procedure $\textsf{Select}(S, r)$ takes a set $S$ of numbers and a rank $r\left(1 \leq r \leq |S|\right)$ and returns the element in $S$ of rank $r$. The procedure $\textsf{MultiSelect}(S,R)$ takes a set of numbers $S$ and a list of ranks $R=\left\{r_{1} < r_{2} < \ldots <r_{k}\right\}$, and returns the list $\left\{x_{1} < x_{2} < ...<x_{k}\right\}$ of elements of $S$, such that the rank of $x_{i}$ is $r_{i}$. Suppose there is an implementation for $\textsf{Select}(S, r)$ that uses at most  $($ constant ·$|S|)$ binary comparisons between elements of $S$. The minimum number of comparisons needed to implement $\textsf{MultiSelect}(S,R)$ is

  1. constant · $|S| \log |S|$
  2. constant · $|S|$
  3. constant · $|S||R|$
  4. constant · $|R| \log |S|$
  5. constant · $|S|(1 + \log |R|)$

6 Answers

Best answer
8 8 votes

Solution

Correct Answer: (E)

\[ \text{constant} \cdot |S|(1 + \log |R|) \]


Key Observation

Recall the partition method used in Quicksort. The partition procedure places a chosen pivot element in its correct sorted position. If the partition returns an index \(k\), then the pivot element is exactly the \(k\)-th smallest element in the array.

Now consider the procedure \(\textsf{Select}(S, r)\). This procedure returns the element of rank \(r\) and also ensures that this element is placed in its correct position, with all elements smaller than it on the left and all larger elements on the right. Even if an implementation does not explicitly rearrange the array, this rearrangement can be done without affecting the asymptotic number of comparisons.

Hence, \(\textsf{Select}\) behaves in the same way as a partition step.


Objective

Efficiently implement \(\textsf{MultiSelect}(S, R)\), where \[ R = \{ r_1 < r_2 < \cdots < r_k \}. \]


Divide-and-Conquer Strategy

To understand the approach clearly, consider the following example: \[ R = \{2, 4, 6, 8, 10, 12\}. \] This means we want to find the 2nd, 4th, 6th, 8th, 10th, and 12th smallest elements of the set \(S\).

  1. First, choose the middle rank from \(R\). In this example, the middle rank is \(8\). Compute \(\textsf{Select}(S, 8)\), which finds the 8th smallest element using \(O(|S|)\) comparisons.
  2. After this operation, the 8th smallest element is placed in its correct position. All elements smaller than it lie to its left, and all elements larger than it lie to its right.
  3. The remaining ranks now split naturally around 8. The ranks \(\{2, 4, 6\}\) correspond to elements that must lie in the left subarray, while the ranks \(\{10, 12\}\) correspond to elements that must lie in the right subarray.
  4. Next, apply the same idea recursively on both sides. To find the 4th smallest element, apply \(\textsf{Select}\) only on the left subarray. To find the 10th smallest element, apply \(\textsf{Select}\) only on the right subarray. Even though two selection operations are performed, the total number of comparisons at this level is still \(O(|S|)\).
  5. After locating the 4th, 8th, and 10th smallest elements, the array is divided into four parts:
    • Elements smaller than the 4th smallest element
    • Elements between the 4th and 8th smallest elements
    • Elements between the 8th and 10th smallest elements
    • Elements larger than the 10th smallest element
  6. The same process is applied recursively to each part that contains at least one required rank. At each level of recursion, the number of selected ranks doubles, while the total work done at that level remains proportional to \(|S|\).

Cost Analysis

At each level of recursion, the total number of comparisons is \(O(|S|)\). The number of levels required to process all \(|R|\) ranks is: \[ \log |R| + 1. \]

Therefore, the total number of comparisons is: \[ O(|S|) \times (\log |R| + 1) = \text{constant} \cdot |S|(1 + \log |R|). \]


Final Answer

\[ \boxed{\text{constant} \cdot |S|(1 + \log |R|)} \]

Hence, the correct option is (E).


A similar question can be found on page 6, question number 5, available at the following link: practicefinalsol.pdf .

• edited by
6 6 votes


1) Find rank of elements of S is Constant*|S|



2) Check for each member, take it's rank of element  and search in input list of required ranks; if found print it !

we have an entry in list of Ranks R, As R is given as sorted we perform binary search over it .

So Comparison : Constant * |S| * Log |R|
 

Total Comparison :  Constant * |S| + Constant * |S| * Log |R| = Constant  * |S| ( 1 + log |R| ) Ans (E)

 

For clarity image : https://drive.google.com/open?id=1hnIVb86YsTdDVPDbOXfOwlMCKL48z1Ks

Note :- assuming those are positive integers.

• edited by
4 4 votes
a) should be the answer

Reason: Sort the set. Initialize a counter to 1. Keep a parallel pointer to the sorted list of needed ranks. Keep incrementing the counter as you traverse the sorted set. As soon as counter matches the first needed rank, add this to the required output. Increment the parallel pointer.
0 0 votes
I think C should be the answer. Using randomized partition algo of quick sort, we can find out kth smallest element in S + S/2 + S/4 + S/8 + ...... = constant.|S| number of comparisions. For proof see Randomized quick sort algo works in nlogn time in worst case also.

So for R (equal to S in worst case) number of comparisions equals to constant.|S|.|R|. Correct me if i am wrong.
0 0 votes

Using Heap : 

We have set S with |S| elements and rank R of each element.

Build heap with ranks R : O(R) 

For each element it takes O(S) to find R.

Searching in heap : 

log R + log R +....+ S times

log ( R ^S ) = > O(SlogR) 

 

Official Key : 

Option e . 

p.s : So may be I am missing something )

0 0 votes
Answer-E

Think about partition method in quick sort. it places pivot to correct location and return the index of pivot element. Now suppose partition returns k then can you tell me what is kth smallest element ?

Yes that’s right – Pivot element is kth smallest element. (Think about it).

Select also does same thing. 𝖲𝖾𝗅𝖾𝖼𝗍(S,r) will not only return rth smallest element but it also places rth smallest to its correct position just like pivot. (if their implementation of 𝖲𝖾𝗅𝖾𝖼𝗍(S,r) is not doing so then I will find rth smallest and i will rearrange my array manually but lets not worry about it).

 

Now comes main part. How to implement 𝖬𝗎𝗅𝗍𝗂𝖲𝖾𝗅𝖾𝖼𝗍() efficiently ?

I am taking an example to explain idea. Suppose R = {2,4,6,8,10,12}. which means you want 2nd smallest, 4th smallest, 6th smallest and so on.

I will pick middle element of R which is 8 and i will search for 8th smallest first. We can do it in O(S).

Here is an crucial observation-

Once we get 8th smallest then how our array looks like ? – 8th smallest is at its correct position.              if 8th smallest is at its correct position then where is 4th smallest ? – left side of array of 8th smallest.   where is 12th smallest? –  right side of array of 8th smallest.

Now I will search for 4th smallest. Now do i need to search 4th smallest in entire array ? – No, I can just search in left side of 8th smallest. Suppose there are K elements on left side and |S|-K elements on right side.

I will find 4th smallest in left side and 10th smallest in right side. but total only |S| comparisions (K for 4th smallest and |S|-K for 10th smallest). This says that we can find 2 elements in |S| comparisons.

After this my array is having 4th smallest, 8th smallest and 10th smallest at its correct position. basically i can divide my array in 4 parts now.

1st part  – left side of 4th smallest

2nd part – between 4th smallest and 8th smallest

3rd part – between 8th smallest and 10th smallest

4th part- after 10th smallest.

How many element i can find in just |S| comparisons now ? – yes 4 elements. Anything having rank smaller than 4 i will search in first part only and so on.

 

Whats the pattern ?

Initially We took |S| comparisions for 1 element (8th smallest)

then we took |S| comparisions for 2 elements (4th and 10th  smallest)

then we take |S| comparisions for 4 elements.

Just draw a tree. Start with array, then divide it into 2 parts and then 4 parts and so on.

Since there are total |R| elements so tree height will be log|R| and at each level we are spending |S| comparisions.

total |S|log|R| comparisons. If you do it carefully then there will be log|R|+1 levels. giving you E as answer.

You can consider constant multiplier for reaaranging array(choose pivot as kth smallest and partition method from quick sort will rearrange array).
Answer:
Position:
Show:

Related questions

26 26 votes
2 answers 2 answers
5.4k
5.4k views
Misbah Ghaya asked Nov 7, 2015
5,356 views
It takes $O(n)$ time to find the median in a list of $n$ elements, which are not necessarily in sorted order while it takes only $O(1)$ time to find the median in a list ...
29 29 votes
3 answers 3 answers
8.2k
8.2k views
Misbah Ghaya asked Nov 6, 2015
8,237 views
Given a weighted directed graph with $n$ vertices where edge weights are integers (positive, zero, or negative), determining whether there are paths of arbitrarily large ...
8 8 votes
2 2 answers
2.8k
2.8k views
Misbah Ghaya asked Nov 7, 2015
2,754 views
Let $G$ be an undirected graph with $n$ vertices. For any subset $S$ of vertices, the set of neighbours of $S$ consists of the union of $S$ and the set of vertices $S'$ t...
34 34 votes
4 answers 4 answers
5.8k
5.8k views
Misbah Ghaya asked Nov 8, 2015
5,837 views
Suppose $n$ processors are connected in a linear array as shown below. Each processor has a number. The processors need to exchange numbers so that the numbers eventually...