Kth smallest element

Problem Statement:

find the kth smallest element in the array.

Algorithm

1. We modify quick sort algorithm to get the kth smallest element.

2. once we get the pivot element using quick_partition() , we check if pivot is k then kth smallest si a[pivot]

3. if k is less than pivot then call quick_select on subarray a[0...pivot] since kth smallest is in this array.

4. if k is greater than pivot then call quick_select on subarray a[pivot...end] with k = k-pivot (measuring k w.r.t pivot ) since kth element is in right side of pivot.

Code :

    // using quick select
    #include <bits/stdc++.h>
    
    using namespace std;
    
    int quick_partition(int a[], int start, int end)
    {
        int pivot = end;
        int i = start;
        int j = i;
    
        /*  for every element a[j] if a[j] <= a[pivot]
            then  swap it with position a[i] and increse both i and j by 1
            else increase j  by 1*/
    
        while (j < end)
        {
            if (a[j] <= a[pivot])
            {
                swap(a[i], a[j]);
                i++;
            }
            j++;
        }
        /* finally i will be the first position where a[i]>a[pivot] 
        so we swap these and pivot will be ith position*/
    
        swap(a[i], a[pivot]);
        return i;
    }
    
    int quick_select_kth(int a[], int start, int end, int k)
    {
    
        int pivot;
        while (start <= end)
        {
            pivot = quick_partition(a, start, end);
            int pivot_distance = pivot - start + 1;
            //   cout << "start = " << start << "  end = " << end << " pivot = " << pivot << "\n";
    
            if (pivot_distance == k)
            {
                return a[pivot];
            }
            else if (pivot_distance > k)
            {
                end = pivot - 1;
            }
            else
            {
                k -= pivot_distance;
                start = pivot + 1;
            }
        }
            return INT_MAX;
    }
    
    int main()
    {
        int n, k;
        cout << "Enter n: ";
        cin >> n;
        int a[n];
        for (int i = 0; i < n; i++)
        {
            cin >> a[i];
        }
        cout << "Enter k: ";
        cin >> k;
        cout << "\n";
        int element = quick_select_kth(a, 0, n - 1, k );
        cout << k << "th smallest = " << element << "\n";
        // for (int i = 0; i < n; i++)
        // {
        //     cout << a[i] << " ";
        // }
        // printf("\n");
    }
                
                
    

Complexity Analysis :

best case : \(O(n)\)

worst case : \(O(n^2)\)

Algorithm

1. In this algoithm we use median of medians as pivot in quick_partion. Everything else is same.

Code :

    // kth smallest using median of medians as pivot

    #include <bits/stdc++.h>
    using namespace std;
    
    int find_median_of_medians(int a[], int start, int end);
    int quick_partition(int a[], int start, int end);
    int quick_select_kth(int a[], int start, int end, int k);
    
    int main()
    {
        int n, k;
        cout << "Enter n: ";
        cin >> n;
        int a[n];
        for (int i = 0; i < n; i++)
        {
            cin >> a[i];
        }
        cout << "Enter k: ";
        cin >> k;
        cout << "\n";
        int element = quick_select_kth(a, 0, n - 1, k );
        cout << k << "th smallest = " << element << "\n";
        // for (int i = 0; i < n; i++)
        // {
        //     cout << a[i] << " ";
        // }
        // printf("\n");
    }
    
    int find_median_of_medians(int a[], int start, int end)
    {
        int n = end - start + 1;
        int median[(int)ceil((float)n / 5)];
        int i = 0;
        int *ptr = a + start;
        for (; i < n / 5; i++)
        {
            sort(ptr, ptr + 5);
    
            median[i] = *(ptr + 3);
            ptr += 5;
        }
        if (i * 5 < n)
        {
            sort(ptr, ptr + n % 5);
            median[i] = *(ptr + (n % 5) / 2);
            i++;
        }
    
        int median_of_medians;
        if (i == 1)
        {
            median_of_medians = median[i - 1];
        }
        else
        {
            median_of_medians = quick_select_kth(median, 0, i - 1, i / 2);
        }
        return median_of_medians;
    }
    
    int quick_partition(int a[], int start, int end)
    {
    
        // move median to end
        int median_of_medians = find_median_of_medians(a, start, end);
        int x = start;
        for (; x <= end; x++)
        {
            if (a[x] == median_of_medians)
            {
                break;
            }
        }
        swap(a[x], a[end]);
        //////////////////////////////////////////////////
        int pivot = end;
        int i = start;
        int j = i;
    
        /*  for every element a[j] if a[j] <= a[pivot]
            then  swap it with position a[i] and increse both i and j by 1
            else increase j  by 1*/
    
        while (j < end)
        {
            if (a[j] <= a[pivot])
            {
                swap(a[i], a[j]);
                i++;
            }
            j++;
        }
        /* finally i will be the first position where a[i]>a[pivot] 
        so we swap these and pivot will be ith position*/
    
        swap(a[i], a[pivot]);
        return i;
    }
    
    int quick_select_kth(int a[], int start, int end, int k)
    {
    
        int pivot;
        while (start <= end)
        {
            pivot = quick_partition(a, start, end);
            int pivot_distance = pivot - start + 1;
            //   cout << "start = " << start << "  end = " << end << " pivot = " << pivot << "\n";
    
            if (pivot_distance == k)
            {
                return a[pivot];
            }
            else if (pivot_distance > k)
            {
                end = pivot - 1;
            }
            else
            {
                k -= pivot_distance;
                start = pivot + 1;
            }
        }
        return INT_MAX;
    }
                           
                
    

Complexity Analysis :

Time complexity : \(O(n)\)

video resources

web resources

book resources