K-th Element of Merged Two Sorted Arrays

Last Updated : 29 Sep, 2026

Given two sorted arrays a[] of size m and b[] of size n, find the k-th smallest element in the combined sorted sequence of all elements from both arrays.
Assume 1-based indexing for k, and that 1 ≤ k ≤ m + n.

Examples: 

Input: a[] = [2, 3, 6, 7, 9], b[] = [1, 4, 8, 10], k = 5
Output: 6
Explanation: The final sorted array is [1, 2, 3, 4, 6, 7, 8, 9, 10]. The 5th element is 6.

Input: a[] = [1, 2, 2], b[] = [2, 3, 4], k = 4
Output: 2
Explanation: Merged array = [1, 2, 2, 2, 3, 4], 4th element = 2.

Try It Yourself
redirect icon

[Naive Approach] Sorting - O((m + n) × log(m + n)) Time and O(m + n) Space

  • Combine both arrays into a single array.
  • Sort the combined array to get all elements in order.
  • The kth smallest element is returned directly using its index.
C++
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int kthElement(vector<int> &a, vector<int> &b, int k) {

    // to merge both the arrays
    vector<int> arr;

    // add the elements of array a
    for(auto i: a)
        arr.push_back(i);

    // add the elements of array a
    for(auto i: b)
        arr.push_back(i);

    // sort the merged array
    sort(arr.begin(), arr.end());

    // return the kth element
    return arr[k-1];
}

int main() {
    
    vector<int> a = {2, 3, 6, 7, 9};
    vector<int> b = {1, 4, 8, 10};
    int k = 5;
    cout << kthElement(a, b, k);
    
    return 0;
}
Java
import java.util.Collections;
import java.util.ArrayList;

class GfG {

    static int kthElement(int[] a, int[] b, int k) {
        
        // to merge both the arrays
        ArrayList<Integer> arr = new ArrayList<>();
        
        // add the elements of array a
        for (int i : a)
            arr.add(i);
        
        // add the elements of array b
        for (int i : b)
            arr.add(i);
        
        // sort the merged array
        Collections.sort(arr);
        
        // return the kth element
        return arr.get(k - 1);
    }
    
    public static void main(String[] args) {
        int[] a = {2, 3, 6, 7, 9};
        int[] b = {1, 4, 8, 10};
        int k = 5;
        
        System.out.println(kthElement(a, b, k));
    }
}
Python
def kthElement(a, b, k):
    
    # to merge both the arrays
    arr = []
    
    # add the elements of array a
    for i in a:
        arr.append(i)
    
    # add the elements of array b
    for i in b:
        arr.append(i)
    
    # sort the merged array
    arr.sort()
    
    # return the kth element
    return arr[k - 1]

if __name__ == "__main__":
    a = [2, 3, 6, 7, 9]
    b = [1, 4, 8, 10]
    k = 5
    print(kthElement(a, b, k))
C#
using System;
using System.Collections.Generic;

class GfG {

    static int kthElement(int[] a, int[] b, int k) {
        
        // to merge both the arrays
        List<int> arr = new List<int>();
        
        // add the elements of array a
        foreach (int i in a)
            arr.Add(i);
        
        // add the elements of array b
        foreach (int i in b)
            arr.Add(i);
        
        // sort the merged array
        arr.Sort();
        
        // return the kth element
        return arr[k - 1];
    }
    
    static void Main() {
        int[] a = {2, 3, 6, 7, 9};
        int[] b = {1, 4, 8, 10};
        int k = 5;
        
        Console.WriteLine(kthElement(a, b, k));
    }
}
JavaScript
function kthElement(a, b, k) {
    
    // to merge both the arrays
    let arr = [];
    
    // add the elements of array a
    for (let i of a)
        arr.push(i);
    
    // add the elements of array b
    for (let i of b)
        arr.push(i);
    
    // sort the merged array
    arr.sort((x, y) => x - y);
    
    // return the kth element
    return arr[k - 1];
}

// Driver Code
let a = [2, 3, 6, 7, 9];
let b = [1, 4, 8, 10];
let k = 5;
console.log(kthElement(a, b, k));

Output
6

[Better Approach] Merge of Merge Sort - O(k) Time and O(1) Space

The idea is to simulate the process of merging two sorted arrays, similar to the merge step in merge sort, but only until the k-th element is reached.

We use two pointers, one for each array. At each step, we choose the smaller of the two current elements to move forward. We only track the last selected element, which will be the k-th smallest.

C++
#include <iostream>
#include <vector>
using namespace std;

int kthElement(vector<int> &a, vector<int> &b, int k){
    int n = a.size(), m = b.size();
  
    // last element added to the merged 
    // sorted array
    int last = 0;
    int i = 0, j = 0;

    for (int d = 0; d < k; ++d) {
        if (i < n) {
          
            // if a[i] > b[j] then increment j
            if (j < m && a[i] > b[j]) {
                last = b[j];
                j++;
            } 
            // otherwise increment i
            else {
                last = a[i];
                i++;
            }
        }
        
        // if reached end of first array then 
        // increment j
        else if (j < m) {
            last = b[j];
            j++;
        }
    }

    // return the last (kth) element
    return last;
}

int main() {
    vector<int> a = {2, 3, 6, 7, 9};
    vector<int> b = {1, 4, 8, 10};
    int k = 5;

    cout << kthElement(a, b, k) << endl;
    return 0;
}
Java
class GfG {
    static int kthElement(int[] a, int[] b, int k){
        int n = a.length, m = b.length;
      
        // last element added to the merged 
        // sorted array
        int last = 0;
      	int i = 0, j = 0;

        for (int d = 0; d < k; ++d) {
            if (i < n) {
              
              	// if a[i] > b[j] then increment j
                if (j < m && a[i] > b[j]) {
                    last = b[j];
                    j++;
                } 
              	
              	// otherwise increment i
              	else {
                    last = a[i];
                    i++;
                }
            } 
          	
          	// if reached end of first array then 
          	// increment j
          	else if (j < m) {
                last = b[j];
                j++;
            }
        }
	
      	// return the last (kth) element
        return last;
    }

    public static void main(String[] args) {
        int[] a = {2, 3, 6, 7, 9};
        int[] b = {1, 4, 8, 10};
        int k = 5;
        System.out.println(kthElement(a, b, k));
    }
}
Python
def kthElement(a, b, k):
    n, m = len(a), len(b)
    
    # last element added to the merged 
    # sorted array
    last = 0
    i, j = 0, 0

    for _ in range(k):
        if i < n:
            # If a[i] > b[j] then increment j
            if j < m and a[i] > b[j]:
                last = b[j]
                j += 1
            # Otherwise increment i
            else:
                last = a[i]
                i += 1
        
        # if reached end of first array then 
        # increment j
        elif j < m:
            last = b[j]
            j += 1

    # Return the last (kth) element
    return last

if __name__ == "__main__":
    a = [2, 3, 6, 7, 9]
    b = [1, 4, 8, 10]
    k = 5
    print(kthElement(a, b, k))
C#
using System;
class GfG {
    static int kthElement(int[] a, int[] b, int k){
        int n = a.Length, m = b.Length;
      
        // last element added to the merged
        // sorted array
        int last = 0;
        int i = 0, j = 0;

        for (int d = 0; d < k; ++d) {
            if (i < n) {
                
                // if a[i] > b[j] then increment j
                if (j < m && a[i] > b[j]) {
                    last = b[j];
                    j++;
                }
                
                // otherwise increment i
                else {
                    last = a[i];
                    i++;
                }
            }
            // if reached end of first array then 
            // increment j
            else if (j < m) {
                last = b[j];
                j++;
            }
        }

        // return the last (kth) element
        return last;
    }

    public static void Main(string[] args) {
        int[] a = { 2, 3, 6, 7, 9 };
        int[] b = { 1, 4, 8, 10 };
        int k = 5;

        Console.WriteLine(kthElement(a, b, k));
    }
}
JavaScript
function kthElement(a, b, k) {
    const n = a.length, m = b.length;
    // last element added to the merged 
    // sorted array
    let last = 0;
    let i = 0, j = 0;

    for (let d = 0; d < k; ++d) {
        if (i < n) {
            // if a[i] > b[j] then increment j
            if (j < m && a[i] > b[j]) {
                last = b[j];
                j++;
            } 
            
            // otherwise increment i
            else {
                last = a[i];
                i++;
            }
        } 
        // if reached end of first array then 
        // increment j
        else if (j < m) {
            last = b[j];
            j++;
        }
    }

    // return the last (kth) element
    return last;
}

// Driver code
const a = [2, 3, 6, 7, 9];
const b = [1, 4, 8, 10];
const k = 5;
console.log(kthElement(a, b, k));

Output
6

[Expected Approach] Binary Search - O(log min(n, m)) Time and O(1) Space

The approach is similar to the Binary Search approach of Median of two sorted arrays of different sizes.

Consider the first array is smaller. If first array is greater, then swap the arrays to make sure that the first array is smaller.

  • We mainly maintain two sets in this algorithm by doing binary search in the smaller array. Let mid1 be the partition of the smaller array. The first set contains elements from 0 to (mid1 – 1) from smaller array and mid2 = (k – mid1) elements from the greater array to make sure that the first set has exactly k elements. The second set contains remaining elements.
  • Our target is to find a point in both arrays such that all elements in the first set are smaller than all elements in the other set (set that contains elements from right side). For this we validate the partitions using the same way as we did in Median of two sorted arrays of different sizes.


C++
#include <iostream>
#include <vector>
#include <climits>
using namespace std;

int kthElement(vector<int> &a, vector<int> &b, int k) {
    int n = a.size(), m = b.size();

    // if a[] has more elements, then call 
    // kthElement with reversed parameters
    if (n > m)
        return kthElement(b, a, k);

    // binary Search on the number of elements we can
    // include in the first set from a[]
    int lo = max(0, k - m), hi = min(k, n);
  
    while (lo <= hi) {
        int mid1 = (lo + hi) / 2;
        int mid2 = k - mid1;

        // find elements to the left and right of 
        // partition in a[]
        int l1 = (mid1 == 0 ? INT_MIN : a[mid1 - 1]);
        int r1 = (mid1 == n ? INT_MAX : a[mid1]);

        // find elements to the left and right of 
        // partition in b[]
        int l2 = (mid2 == 0 ? INT_MIN : b[mid2 - 1]);
        int r2 = (mid2 == m ? INT_MAX : b[mid2]);

        // if it is a valid partition
        if (l1 <= r2 && l2 <= r1) {
          	
          	// find and return the maximum of l1 and l2
            return max(l1, l2);
        }

        // check if we need to take lesser elements from a[]
        if (l1 > r2)
            hi = mid1 - 1;

        // check if we need to take more elements from a[]
        else
            lo = mid1 + 1;
    }
  
    return 0;
}

int main() {
    vector<int> a = {2, 3, 6, 7, 9};
    vector<int> b = {1, 4, 8, 10};
    int k = 5;
    cout << kthElement(a, b, k);
    return 0;
}
Java
class GfG {
    static int kthElement(int[] a, int[] b, int k) {
        int n = a.length, m = b.length;

        // if a[] has more elements, then call 
        // kthElement with reversed parameters
        if (n > m)
            return kthElement(b, a, k);

        // binary Search on the number of elements we 
        // can include in the first set from a[]
        int lo = Math.max(0, k - m), hi = Math.min(k, n);

        while (lo <= hi) {
            int mid1 = (lo + hi) / 2;
            int mid2 = k - mid1;

            // find elements to the left and right of 
            // partition in a[]
            int l1 = (mid1 == 0 ? Integer.MIN_VALUE : 
                      					a[mid1 - 1]);
            int r1 = (mid1 == n ? Integer.MAX_VALUE : 
                      						a[mid1]);

            // find elements to the left and right of 
            // partition in a[]
            int l2 = (mid2 == 0 ? Integer.MIN_VALUE : 
                      					b[mid2 - 1]);
            int r2 = (mid2 == m ? Integer.MAX_VALUE :
                      						b[mid2]);

            // if it is a valid partition
            if (l1 <= r2 && l2 <= r1) {
                // find and return the maximum of l1 and l2
                return Math.max(l1, l2);
            }

            // check if we need to take lesser elements
            // from a[]
            if (l1 > r2)
                hi = mid1 - 1;

            // check if we need to take more elements 
            // from a[]
            else
                lo = mid1 + 1;
        }

        return 0;
    }

    public static void main(String[] args) {
        int[] a = {2, 3, 6, 7, 9};
        int[] b = {1, 4, 8, 10};
        int k = 5;
        System.out.println(kthElement(a, b, k));
    }
}
Python
def kthElement(a, b, k):
    n = len(a)
    m = len(b)

    # if a[] has more elements, then call kthElement
    # with reversed parameters
    if n > m:
        return kthElement(b, a, k)

    # binary Search on the number of elements we can
    # include in the first set from a[]
    lo = max(0, k - m)
    hi = min(k, n)

    while lo <= hi:
        mid1 = (lo + hi) // 2
        mid2 = k - mid1

        # find elements to the left and right of
        # partition in a[]
        l1 = (mid1 == 0 and float('-inf') or a[mid1 - 1])
        r1 = (mid1 == n and float('inf') or a[mid1])

        # find elements to the left and right of
        # partition in b[]
        l2 = (mid2 == 0 and float('-inf') or b[mid2 - 1])
        r2 = (mid2 == m and float('inf') or b[mid2])

        # if it is a valid partition
        if l1 <= r2 and l2 <= r1:
          
            # find and return the maximum of l1 and l2
            return max(l1, l2)

        # check if we need to take lesser elements 
        # from a[]
        if l1 > r2:
            hi = mid1 - 1

        # check if we need to take more elements
        # from a[]
        else:
            lo = mid1 + 1

    return 0

if __name__ == "__main__":
    a = [2, 3, 6, 7, 9]
    b = [1, 4, 8, 10]
    k = 5
    print(kthElement(a, b, k))
C#
using System;
class GfG {
    static int kthElement(int[] a, int[] b, int k) {
        int n = a.Length, m = b.Length;

        // if a[] has more elements, then call kthElement
        // with reversed parameters
        if (n > m)
            return kthElement(b, a, k);

        // binary Search on the number of elements we can
        // include in the first set from a[]
        int lo = Math.Max(0, k - m), hi = Math.Min(k, n);

        while (lo <= hi) {
            int mid1 = (lo + hi) / 2;
            int mid2 = k - mid1;

            // find elements to the left and right of 
            // partition in a[]
            int l1 = (mid1 == 0 ? Int32.MinValue : a[mid1 - 1]);
            int r1 = (mid1 == n ? Int32.MaxValue : a[mid1]);

            // find elements to the left and right of 
            // partition in b[]
            int l2 = (mid2 == 0 ? Int32.MinValue : b[mid2 - 1]);
            int r2 = (mid2 == m ? Int32.MaxValue : b[mid2]);

            // if it is a valid partition
            if (l1 <= r2 && l2 <= r1) {
              
                // find and return the maximum of l1 and l2
                return Math.Max(l1, l2);
            }

            // check if we need to take lesser
            // elements from a[]
            if (l1 > r2)
                hi = mid1 - 1;

            // check if we need to take more
            // elements from a[]
            else
                lo = mid1 + 1;
        }

        return 0;
    }

    static void Main() {
        int[] a = { 2, 3, 6, 7, 9 };
        int[] b = { 1, 4, 8, 10 };
        int k = 5;
        Console.WriteLine(kthElement(a, b, k));
    }
}
JavaScript
function kthElement(a, b, k) {
    let n = a.length, m = b.length;

    // if a[] has more elements, then call kthElement
    // with reversed parameters
    if (n > m) {
        return kthElement(b, a, k);
    }

    // binary Search on the number of elements we can
    // include in the first set from a[]
    let lo = Math.max(0, k - m), hi = Math.min(k, n);

    while (lo <= hi) {
        let mid1 = Math.floor((lo + hi) / 2);
        let mid2 = k - mid1;

        // find elements to the left and right of partition in a[]
        let l1 = (mid1 === 0 ? -Infinity : a[mid1 - 1]);
        let r1 = (mid1 === n ? Infinity : a[mid1]);

        // find elements to the left and right of partition in b[]
        let l2 = (mid2 === 0 ? -Infinity : b[mid2 - 1]);
        let r2 = (mid2 === m ? Infinity : b[mid2]);

        // if it is a valid partition
        if (l1 <= r2 && l2 <= r1) {

            // find and return the maximum of l1 and l2
            return Math.max(l1, l2);
        }

        // check if we need to take lesser 
        // elements from a[]
        if (l1 > r2) {
            hi = mid1 - 1;
        }

        // check if we need to take more 
        // elements from a[]
        else {
            lo = mid1 + 1;
        }
    }

    return 0;
}

// Driver Code
const a = [2, 3, 6, 7, 9];
const b = [1, 4, 8, 10];
const k = 5;
console.log(kthElement(a, b, k));

Output
6
Comment