📜  两个有序数组的第 K 个元素

📅  最后修改于: 2021-09-16 10:56:42             🧑  作者: Mango

给定两个大小分别为 m 和 n 的排序数组,您的任务是找到位于最终排序数组第 k 个位置的元素。

例子:

Input : Array 1 - 2 3 6 7 9
        Array 2 - 1 4 8 10
        k = 5
Output : 6
Explanation: The final sorted array would be -
1, 2, 3, 4, 6, 7, 8, 9, 10
The 5th element of this array is 6.

Input : Array 1 - 100 112 256 349 770
        Array 2 - 72 86 113 119 265 445 892
        k = 7
Output : 256
Explanation: Final sorted array is -
72, 86, 100, 112, 113, 119, 256, 265, 349, 445, 770, 892
7th element of this array is 256.

基本方法
由于给定了两个已排序的数组,我们可以使用合并技术来获得最终的合并数组。由此,我们只需转到第 k 个索引。

C++
// Program to find kth element from two sorted arrays
#include 
using namespace std;
 
int kth(int arr1[], int arr2[], int m, int n, int k)
{
    int sorted1[m + n];
    int i = 0, j = 0, d = 0;
    while (i < m && j < n)
    {
        if (arr1[i] < arr2[j])
            sorted1[d++] = arr1[i++];
        else
            sorted1[d++] = arr2[j++];
    }
    while (i < m)
        sorted1[d++] = arr1[i++];
    while (j < n)
        sorted1[d++] = arr2[j++];
    return sorted1[k - 1];
}
 
// Driver Code
int main()
{
    int arr1[5] = {2, 3, 6, 7, 9};
    int arr2[4] = {1, 4, 8, 10};
    int k = 5;
    cout << kth(arr1, arr2, 5, 4, k);
    return 0;
}


Java
// Java Program to find kth element
// from two sorted arrays
 
class Main
{
    static int kth(int arr1[], int arr2[], int m, int n, int k)
    {
        int[] sorted1 = new int[m + n];
        int i = 0, j = 0, d = 0;
        while (i < m && j < n)
        {
            if (arr1[i] < arr2[j])
                sorted1[d++] = arr1[i++];
            else
                sorted1[d++] = arr2[j++];
        }
        while (i < m)
            sorted1[d++] = arr1[i++];
        while (j < n)
            sorted1[d++] = arr2[j++];
        return sorted1[k - 1];
    }
     
    // Driver Code
    public static void main (String[] args)
    {
        int arr1[] = {2, 3, 6, 7, 9};
        int arr2[] = {1, 4, 8, 10};
        int k = 5;
        System.out.print(kth(arr1, arr2, 5, 4, k));
    }
}
 
/* This code is contributed by Harsh Agarwal */


Python3
# Program to find kth element
# from two sorted arrays
 
 
def kth(arr1, arr2, m, n, k):
 
    sorted1 = [0] * (m + n)
    i = 0
    j = 0
    d = 0
    while (i < m and j < n):
 
        if (arr1[i] < arr2[j]):
            sorted1[d] = arr1[i]
            i += 1
        else:
            sorted1[d] = arr2[j]
            j += 1
        d += 1
 
    while (i < m):
        sorted1[d] = arr1[i]
        d += 1
        i += 1
    while (j < n):
        sorted1[d] = arr2[j]
        d += 1
        j += 1
    return sorted1[k - 1]
 
 
# Driver code
arr1 = [2, 3, 6, 7, 9]
arr2 = [1, 4, 8, 10]
k = 5
print(kth(arr1, arr2, 5, 4, k))
 
# This code is contributed by Smitha Dinesh Semwal


C#
// C# Program to find kth element
// from two sorted arrays
class GFG {
    static int kth(int[] arr1, int[] arr2, int m, int n,
                   int k)
    {
        int[] sorted1 = new int[m + n];
        int i = 0, j = 0, d = 0;
        while (i < m && j < n) {
            if (arr1[i] < arr2[j])
                sorted1[d++] = arr1[i++];
            else
                sorted1[d++] = arr2[j++];
        }
        while (i < m)
            sorted1[d++] = arr1[i++];
        while (j < n)
            sorted1[d++] = arr2[j++];
        return sorted1[k - 1];
    }
 
    // Driver Code
    static void Main()
    {
        int[] arr1 = { 2, 3, 6, 7, 9 };
        int[] arr2 = { 1, 4, 8, 10 };
        int k = 5;
        System.Console.WriteLine(kth(arr1, arr2, 5, 4, k));
    }
}
 
// This code is contributed by mits


PHP


Javascript


C++
// C++ program to find kth element
// from two sorted arrays
#include 
using namespace std;
 
int find(int A[], int B[], int m,
         int n, int k_req)
{
    int k = 0, i = 0, j = 0;
 
    // Keep taking smaller of the current
    // elements of two sorted arrays and
    // keep incrementing k
    while(i < m && j < n)
    {
        if(A[i] < B[j])
        {
            k++;
            if(k == k_req)
                return A[i];
            i++;
        }
        else
        {
            k++;
            if(k == k_req)
                return B[j];
            j++;
        }
    }
 
    // If array B[] is completely traversed
    while(i < m)
    {
        k++;
        if(k == k_req)
            return A[i];
        i++;
    }
 
    // If array A[] is completely traversed
    while(j < n)
    {
        k++;
        if(k == k_req)
            return B[j];
        j++;
    }
}
 
// Driver Code
int main()
{
    int A[5] = { 2, 3, 6, 7, 9 };
    int B[4] = { 1, 4, 8, 10 };
    int k = 5;
     
    cout << find(A, B, 5, 4, k);
     
    return 0;
}
 
// This code is contributed by Sreejith S


Java
import java.io.*;
 
class GFG {
    public static int find(int A[], int B[], int m, int n,
                           int k_req)
    {
        int k = 0, i = 0, j = 0;
 
        // Keep taking smaller of the current
        // elements of two sorted arrays and
        // keep incrementing k
        while (i < m && j < n) {
            if (A[i] < B[j]) {
                k++;
                if (k == k_req)
                    return A[i];
                i++;
            }
            else {
                k++;
                if (k == k_req)
                    return B[j];
                j++;
            }
        }
 
        // If array B[] is completely traversed
        while (i < m) {
            k++;
            if (k == k_req)
                return A[i];
            i++;
        }
 
        // If array A[] is completely traversed
        while (j < n) {
            k++;
            if (k == k_req)
                return B[j];
            j++;
        }
        return -1;
    }
 
    // Driver Code
    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(find(A, B, 5, 4, k));
    }
}


Python3
# Python3 Program to find kth element
# from two sorted arrays
 
def find(A, B, m, n, k_req):   
    i, j, k = 0, 0, 0
 
    # Keep taking smaller of the current
    # elements of two sorted arrays and
    # keep incrementing k
    while i < len(A) and j < len(B):
        if A[i] < B[j]:
            k += 1
            if k == k_req:
                return A[i]
            i += 1
        else:
            k += 1
            if k == k_req:
                return B[j]       
            j += 1
 
    # If array B[] is completely traversed
    while i < len(A):
        k += 1
        if k == k_req:
                return A[i]
        i += 1
 
 
    # If array A[] is completely traversed
    while j < len(B):
        k += 1
        if k == k_req:
                return B[j]
        j += 1
 
# driver code
A = [2, 3, 6, 7, 9]
B = [1, 4, 8, 10]
k = 5;
print(find(A, B, 5, 4, k))
# time complexity of O(k)


C#
// C# program to find kth element
// from two sorted arrays
using System;
public class GFG
{
 
  public static int find(int[] A, int[] B,
                         int m, int n,int k_req)
  {
    int k = 0, i = 0, j = 0;
 
    // Keep taking smaller of the current
    // elements of two sorted arrays and
    // keep incrementing k
    while (i < m && j < n) {
      if (A[i] < B[j]) {
        k++;
        if (k == k_req)
          return A[i];
        i++;
      }
      else {
        k++;
        if (k == k_req)
          return B[j];
        j++;
      }
    }
 
    // If array B[] is completely traversed
    while (i < m)
    {
      k++;
      if (k == k_req)
        return A[i];
      i++;
    }
 
    // If array A[] is completely traversed
    while (j < n)
    {
      k++;
      if (k == k_req)
        return B[j];
      j++;
    }
    return -1;
  }
 
  // Driver Code
  static public void Main (){
    int[] A = { 2, 3, 6, 7, 9 };
    int[] B = { 1, 4, 8, 10 };
    int k = 5;
    Console.WriteLine(find(A, B, 5, 4, k));
  }
}
 
// This code is contributed by rag2127


C++
// Program to find k-th element from two sorted arrays
#include 
using namespace std;
 
int kth(int *arr1, int *arr2, int *end1, int *end2, int k)
{
    if (arr1 == end1)
        return arr2[k];
    if (arr2 == end2)
        return arr1[k];
    int mid1 = (end1 - arr1) / 2;
    int mid2 = (end2 - arr2) / 2;
    if (mid1 + mid2 < k)
    {
        if (arr1[mid1] > arr2[mid2])
            return kth(arr1, arr2 + mid2 + 1, end1, end2,
                k - mid2 - 1);
        else
            return kth(arr1 + mid1 + 1, arr2, end1, end2,
                k - mid1 - 1);
    }
    else
    {
        if (arr1[mid1] > arr2[mid2])
            return kth(arr1, arr2, arr1 + mid1, end2, k);
        else
            return kth(arr1, arr2, end1, arr2 + mid2, k);
    }
}
 
int main()
{
    int arr1[5] = {2, 3, 6, 7, 9};
    int arr2[4] = {1, 4, 8, 10};
 
    int k = 5;
    cout << kth(arr1, arr2, arr1 + 5, arr2 + 4,  k - 1);
    return 0;
}


Python3
# Python program to find k-th element from two sorted arrays
def kth(arr1, arr2, n, m, k):
 
    if n == 1 or m == 1:
        if m == 1:
            arr2, arr1 = arr1, arr2
            m = n
        if k == 1:
            return min(arr1[0], arr2[0])
        elif k == m + 1:
            return max(arr1[0], arr2[0])
        else:
            if arr2[k - 1] < arr1[0]:
                return arr2[k - 1]
            else:
                return max(arr1[0], arr2[k - 2])
 
    mid1 = (n - 1)//2
    mid2 = (m - 1)//2
 
    if mid1+mid2+1 < k:
        if arr1[mid1] < arr2[mid2]:
            return kth(arr1[mid1 + 1:], arr2, n - mid1 - 1, m, k - mid1 - 1)
        else:
            return kth(arr1, arr2[mid2 + 1:], n, m - mid2 - 1, k - mid2 - 1)
    else:
        if arr1[mid1] < arr2[mid2]:
            return kth(arr1, arr2[:mid2 + 1], n, mid2 + 1, k)
        else:
            return kth(arr1[:mid1 + 1], arr2, mid1 + 1, m, k)
 
 
if __name__ == "__main__":
    arr1 = [2, 3, 6, 7, 9]
    arr2 = [1, 4, 8, 10]
    k = 5
    print(kth(arr1, arr2, 5, 4, k))
 
# This code is contributed by harshitkap00r


C++
// C++ Program to find kth element from two sorted arrays
#include 
using namespace std;
 
int kth(int arr1[], int arr2[], int m, int n, int k,
                           int st1 = 0, int st2 = 0)
{
    // In case we have reached end of array 1
    if (st1 == m)
        return arr2[st2 + k - 1];
 
    // In case we have reached end of array 2
    if (st2 == n)
        return arr1[st1 + k - 1];
 
    // k should never reach 0 or exceed sizes
    // of arrays
    if (k == 0 || k > (m - st1) + (n - st2))
        return -1;
 
    // Compare first elements of arrays and return
    if (k == 1)
        return (arr1[st1] < arr2[st2]) ?
            arr1[st1] : arr2[st2];
    int curr = k / 2;
 
    // Size of array 1 is less than k / 2
    if (curr - 1 >= m - st1)
    {
        // Last element of array 1 is not kth
        // We can directly return the (k - m)th
        // element in array 2
        if (arr1[m - 1] < arr2[st2 + curr - 1])
            return arr2[st2 + (k - (m - st1) - 1)];
        else
            return kth(arr1, arr2, m, n, k - curr,
                st1, st2 + curr);
    }
 
    // Size of array 2 is less than k / 2
    if (curr-1 >= n-st2)
    {
        if (arr2[n - 1] < arr1[st1 + curr - 1])
            return arr1[st1 + (k - (n - st2) - 1)];
        else
            return kth(arr1, arr2, m, n, k - curr,
                st1 + curr, st2);
    }
    else
    {
        // Normal comparison, move starting index
        // of one array k / 2 to the right
        if (arr1[curr + st1 - 1] < arr2[curr + st2 - 1])
            return kth(arr1, arr2, m, n, k - curr,
                st1 + curr, st2);
        else
            return kth(arr1, arr2, m, n, k - curr,
                st1, st2 + curr);
    }
}
 
// Driver code
int main()
{
    int arr1[5] = {2, 3, 6, 7, 9};
    int arr2[4] = {1, 4, 8, 10};
 
    int k = 5;
    cout << kth(arr1, arr2, 5, 4,  k);
    return 0;
}


Java
// Java Program to find kth element from two sorted arrays
class GFG
{
 
    static int kth(int arr1[], int arr2[], int m,
                   int n, int k, int st1, int st2)
    {
        // In case we have reached end of array 1
        if (st1 == m)
        {
            return arr2[st2 + k - 1];
        }
 
        // In case we have reached end of array 2
        if (st2 == n)
        {
            return arr1[st1 + k - 1];
        }
 
        // k should never reach 0 or exceed sizes
        // of arrays
        if (k == 0 || k > (m - st1) + (n - st2))
        {
            return -1;
        }
 
        // Compare first elements of arrays and return
        if (k == 1)
        {
            return (arr1[st1] < arr2[st2])
                    ? arr1[st1] : arr2[st2];
        }
        int curr = k / 2;
 
        // Size of array 1 is less than k / 2
        if (curr - 1 >= m - st1)
        {
             
            // Last element of array 1 is not kth
            // We can directly return the (k - m)th
            // element in array 2
            if (arr1[m - 1] < arr2[st2 + curr - 1])
            {
                return arr2[st2 + (k - (m - st1) - 1)];
            }
            else
            {
                return kth(arr1, arr2, m, n, k - curr,
                        st1, st2 + curr);
            }
        }
 
        // Size of array 2 is less than k / 2
        if (curr - 1 >= n - st2)
        {
            if (arr2[n - 1] < arr1[st1 + curr - 1])
            {
                return arr1[st1 + (k - (n - st2) - 1)];
            }
            else
            {
                return kth(arr1, arr2, m, n, k - curr,
                        st1 + curr, st2);
            }
        }
        else
         
        // Normal comparison, move starting index
        // of one array k / 2 to the right
        if (arr1[curr + st1 - 1] < arr2[curr + st2 - 1])
        {
            return kth(arr1, arr2, m, n, k - curr,
                    st1 + curr, st2);
        }
        else
        {
            return kth(arr1, arr2, m, n, k - curr,
                    st1, st2 + curr);
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr1[] = {2, 3, 6, 7, 9};
        int arr2[] = {1, 4, 8, 10};
        int k = 5;
        int st1 = 0, st2 = 0;
        System.out.println(kth(arr1, arr2, 5, 4, k, st1, st2));
    }
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to find kth element from
# two sorted arrays
def kth(arr1, arr2, m, n, k, st1 = 0, st2 = 0):
     
    # In case we have reached end of array 1
    if (st1 == m):
        return arr2[st2 + k - 1]
 
    # In case we have reached end of array 2
    if (st2 == n):
        return arr1[st1 + k - 1]
 
    # k should never reach 0 or exceed sizes
    # of arrays
    if (k == 0 or k > (m - st1) + (n - st2)):
        return -1
         
    # Compare first elements of arrays and return
    if (k == 1):
        if(arr1[st1] < arr2[st2]):
            return arr1[st1]
        else:
            return arr2[st2]
 
    curr = int(k / 2)
 
    # Size of array 1 is less than k / 2
    if(curr - 1 >= m - st1):
 
        # Last element of array 1 is not kth
        # We can directly return the (k - m)th
        # element in array 2
        if (arr1[m - 1] < arr2[st2 + curr - 1]):
            return arr2[st2 + (k - (m - st1) - 1)]
        else:
            return kth(arr1, arr2, m, n,
                       k - curr, st1, st2 + curr)
 
    # Size of array 2 is less than k / 2
    if (curr - 1 >= n - st2):
        if (arr2[n - 1] < arr1[st1 + curr - 1]):
            return arr1[st1 + (k - (n - st2) - 1)]
        else:
            return kth(arr1, arr2, m, n,
                       k - curr,st1 + curr, st2)
    else:
         
        # Normal comparison, move starting index
        # of one array k / 2 to the right
        if (arr1[curr + st1 - 1] < arr2[curr + st2 - 1]):
            return kth(arr1, arr2, m, n, k - curr,
                       st1 + curr, st2)
        else:
            return kth(arr1, arr2, m, n, k - curr,
                       st1, st2 + curr)
 
# Driver code
arr1 = [ 2, 3, 6, 7, 9 ]
arr2 = [ 1, 4, 8, 10 ]
k = 5
 
print(kth(arr1, arr2, 5, 4, k))
 
# This code is contributed by avanitrachhadiya2155


C#
// C# Program to find kth element from two sorted arrays
using System;
 
class GFG
{
 
    static int kth(int []arr1, int []arr2, int m,
                int n, int k, int st1, int st2)
    {
        // In case we have reached end of array 1
        if (st1 == m)
        {
            return arr2[st2 + k - 1];
        }
 
        // In case we have reached end of array 2
        if (st2 == n)
        {
            return arr1[st1 + k - 1];
        }
 
        // k should never reach 0 or exceed sizes
        // of arrays
        if (k == 0 || k > (m - st1) + (n - st2))
        {
            return -1;
        }
 
        // Compare first elements of arrays and return
        if (k == 1)
        {
            return (arr1[st1] < arr2[st2])
                    ? arr1[st1] : arr2[st2];
        }
        int curr = k / 2;
 
        // Size of array 1 is less than k / 2
        if (curr - 1 >= m - st1)
        {
             
            // Last element of array 1 is not kth
            // We can directly return the (k - m)th
            // element in array 2
            if (arr1[m - 1] < arr2[st2 + curr - 1])
            {
                return arr2[st2 + (k - (m - st1) - 1)];
            }
            else
            {
                return kth(arr1, arr2, m, n, k - curr,
                        st1, st2 + curr);
            }
        }
 
        // Size of array 2 is less than k / 2
        if (curr - 1 >= n - st2)
        {
            if (arr2[n - 1] < arr1[st1 + curr - 1])
            {
                return arr1[st1 + (k - (n - st2) - 1)];
            }
            else
            {
                return kth(arr1, arr2, m, n, k - curr,
                        st1 + curr, st2);
            }
        }
        else
         
        // Normal comparison, move starting index
        // of one array k / 2 to the right
        if (arr1[curr + st1 - 1] < arr2[curr + st2 - 1])
        {
            return kth(arr1, arr2, m, n, k - curr,
                    st1 + curr, st2);
        }
        else
        {
            return kth(arr1, arr2, m, n, k - curr,
                    st1, st2 + curr);
        }
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int []arr1 = {2, 3, 6, 7, 9};
        int []arr2 = {1, 4, 8, 10};
        int k = 5;
        int st1 = 0, st2 = 0;
        Console.WriteLine(kth(arr1, arr2, 5, 4, k, st1, st2));
    }
}
 
// This code is contributed by PrinciRaj1992


C++
// C++ Program to find kth
// element from two sorted arrays
// Time Complexity: O(log k)
 
#include 
using namespace std;
 
int kth(int arr1[], int m, int arr2[], int n, int k)
{
 
    if (k > (m + n) || k < 1)
        return -1;
 
    // let m <= n
    if (m > n)
        return kth(arr2, n, arr1, m, k);
 
    // Check if arr1 is empty returning
    // k-th element of arr2
    if (m == 0)
        return arr2[k - 1];
 
    // Check if k = 1 return minimum of
    // first two elements of both
    // arrays
    if (k == 1)
        return min(arr1[0], arr2[0]);
 
    // Now the divide and conquer part
    int i = min(m, k / 2), j = min(n, k / 2);
 
    if (arr1[i - 1] > arr2[j - 1])
       
        // Now we need to find only
        // k-j th element since we
        // have found out the lowest j
        return kth(arr1, m, arr2 + j, n - j, k - j);
    else
       
        // Now we need to find only
        // k-i th element since we
        // have found out the lowest i
        return kth(arr1 + i, m - i, arr2, n, k - i);
}
 
// Driver code
int main()
{
    int arr1[5] = { 2, 3, 6, 7, 9 };
    int arr2[4] = { 1, 4, 8, 10 };
    int m = sizeof(arr1) / sizeof(arr1[0]);
    int n = sizeof(arr2) / sizeof(arr2[0]);
    int k = 5;
 
    int ans = kth(arr1, m, arr2, n, k);
 
    if (ans == -1)
        cout << "Invalid query";
    else
        cout << ans;
 
    return 0;
}
// This code is contributed by Raj Kumar


Java
// Java Program to find kth element
// from two sorted arrays
// Time Complexity: O(log k)
import java.util.Arrays;
 
class Gfg {
    static int kth(int arr1[], int m, int arr2[], int n,
                   int k)
    {
        if (k > (m + n) || k < 1)
            return -1;
 
        // let m > n
        if (m > n)
            return kth(arr2, n, arr1, m, k);
 
        // Check if arr1 is empty returning
        // k-th element of arr2
        if (m == 0)
            return arr2[k - 1];
 
        // Check if k = 1 return minimum of first
        // two elements of both arrays
        if (k == 1)
            return Math.min(arr1[0], arr2[0]);
 
        // Now the divide and conquer part
        int i = Math.min(m, k / 2);
        int j = Math.min(n, k / 2);
 
        if (arr1[i - 1] > arr2[j - 1]) {
           
            // Now we need to find only k-j th element
            // since we have found out the lowest j
            int temp[] = Arrays.copyOfRange(arr2, j, n);
            return kth(arr1, m, temp, n - j, k - j);
        }
 
        // Now we need to find only k-i th element
        // since we have found out the lowest i
        int temp[] = Arrays.copyOfRange(arr1, i, m);
        return kth(temp, m - i, arr2, n, k - i);
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr1[] = { 2, 3, 6, 7, 9 };
        int arr2[] = { 1, 4, 8, 10 };
        int m = arr1.length;
        int n = arr2.length;
 
        int k = 5;
        int ans = kth(arr1, m, arr2, n, k);
        if (ans == -1)
            System.out.println("Invalid query");
        else
            System.out.println(ans);
    }
}
 
// This code is contributed by Vivek Kumar Singh


C++
// C++ Program to find kth
// element from two sorted arrays
#include 
using namespace std;
 
// Function to find K-th min
int kth(int* a, int* b, int n, int m, int k)
{
      // Declaring a min heap
    priority_queue,
                   greater > pq;
       
      // Pushing elements for
    // array a to min-heap
    for (int i = 0; i < n; i++) {
        pq.push(a[i]);
    }
   
      // Pushing elements for
    // array b to min-heap
    for (int i = 0; i < m; i++) {
        pq.push(b[i]);
    }
   
      // Poping-out K-1 elements
    while (k-- > 1) {
        pq.pop();
    }
    return pq.top();
}
 
//Driver Code
int main()
{
    int arr1[5] = {2, 3, 6, 7, 9};
    int arr2[4] = {1, 4, 8, 10};
    int k = 5;
    cout << kth(arr1, arr2, 5, 4, k);
    return 0;
}
 
// This code is contributed by yashbeersingh42


Java
// Java Program to find kth element
// from two sorted arrays
import java.util.*;
 
class GFG {
   
    // Function to find K-th min
    static int kth(int a[], int b[],
                   int n, int m, int k)
    {
         
        // Declaring a min heap
        PriorityQueue pq =
                        new PriorityQueue<>();
 
        // Pushing elements for
        // array a to min-heap
        for (int i = 0; i < n; i++) {
            pq.offer(a[i]);
        }
 
        // Pushing elements for
        // array b to min-heap
        for (int i = 0; i < m; i++) {
            pq.offer(b[i]);
        }
 
        // Poping-out K-1 elements
        while (k-- > 1) {
            pq.remove();
        }
        return pq.peek();
    }
   
    // Driver Code
    public static void main(String[] args)
    {
        int arr1[] = { 2, 3, 6, 7, 9 };
        int arr2[] = { 1, 4, 8, 10 };
        int k = 5;
        System.out.print(kth(arr1, arr2, 5, 4, k));
    }
}
 
// This code is contributed by yashbeersingh42


输出
6

时间复杂度: O(n)
辅助空间: O(m + n)

上述方法的空间优化版本:我们可以避免使用额外的数组。

C++

// C++ program to find kth element
// from two sorted arrays
#include 
using namespace std;
 
int find(int A[], int B[], int m,
         int n, int k_req)
{
    int k = 0, i = 0, j = 0;
 
    // Keep taking smaller of the current
    // elements of two sorted arrays and
    // keep incrementing k
    while(i < m && j < n)
    {
        if(A[i] < B[j])
        {
            k++;
            if(k == k_req)
                return A[i];
            i++;
        }
        else
        {
            k++;
            if(k == k_req)
                return B[j];
            j++;
        }
    }
 
    // If array B[] is completely traversed
    while(i < m)
    {
        k++;
        if(k == k_req)
            return A[i];
        i++;
    }
 
    // If array A[] is completely traversed
    while(j < n)
    {
        k++;
        if(k == k_req)
            return B[j];
        j++;
    }
}
 
// Driver Code
int main()
{
    int A[5] = { 2, 3, 6, 7, 9 };
    int B[4] = { 1, 4, 8, 10 };
    int k = 5;
     
    cout << find(A, B, 5, 4, k);
     
    return 0;
}
 
// This code is contributed by Sreejith S

Java

import java.io.*;
 
class GFG {
    public static int find(int A[], int B[], int m, int n,
                           int k_req)
    {
        int k = 0, i = 0, j = 0;
 
        // Keep taking smaller of the current
        // elements of two sorted arrays and
        // keep incrementing k
        while (i < m && j < n) {
            if (A[i] < B[j]) {
                k++;
                if (k == k_req)
                    return A[i];
                i++;
            }
            else {
                k++;
                if (k == k_req)
                    return B[j];
                j++;
            }
        }
 
        // If array B[] is completely traversed
        while (i < m) {
            k++;
            if (k == k_req)
                return A[i];
            i++;
        }
 
        // If array A[] is completely traversed
        while (j < n) {
            k++;
            if (k == k_req)
                return B[j];
            j++;
        }
        return -1;
    }
 
    // Driver Code
    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(find(A, B, 5, 4, k));
    }
}

蟒蛇3

# Python3 Program to find kth element
# from two sorted arrays
 
def find(A, B, m, n, k_req):   
    i, j, k = 0, 0, 0
 
    # Keep taking smaller of the current
    # elements of two sorted arrays and
    # keep incrementing k
    while i < len(A) and j < len(B):
        if A[i] < B[j]:
            k += 1
            if k == k_req:
                return A[i]
            i += 1
        else:
            k += 1
            if k == k_req:
                return B[j]       
            j += 1
 
    # If array B[] is completely traversed
    while i < len(A):
        k += 1
        if k == k_req:
                return A[i]
        i += 1
 
 
    # If array A[] is completely traversed
    while j < len(B):
        k += 1
        if k == k_req:
                return B[j]
        j += 1
 
# driver code
A = [2, 3, 6, 7, 9]
B = [1, 4, 8, 10]
k = 5;
print(find(A, B, 5, 4, k))
# time complexity of O(k)

C#

// C# program to find kth element
// from two sorted arrays
using System;
public class GFG
{
 
  public static int find(int[] A, int[] B,
                         int m, int n,int k_req)
  {
    int k = 0, i = 0, j = 0;
 
    // Keep taking smaller of the current
    // elements of two sorted arrays and
    // keep incrementing k
    while (i < m && j < n) {
      if (A[i] < B[j]) {
        k++;
        if (k == k_req)
          return A[i];
        i++;
      }
      else {
        k++;
        if (k == k_req)
          return B[j];
        j++;
      }
    }
 
    // If array B[] is completely traversed
    while (i < m)
    {
      k++;
      if (k == k_req)
        return A[i];
      i++;
    }
 
    // If array A[] is completely traversed
    while (j < n)
    {
      k++;
      if (k == k_req)
        return B[j];
      j++;
    }
    return -1;
  }
 
  // Driver Code
  static public void Main (){
    int[] A = { 2, 3, 6, 7, 9 };
    int[] B = { 1, 4, 8, 10 };
    int k = 5;
    Console.WriteLine(find(A, B, 5, 4, k));
  }
}
 
// This code is contributed by rag2127
输出
6

时间复杂度: O(k)
辅助空间: O(1)

  1. 分而治之法1
    虽然之前的方法有效,但我们可以让我们的算法更高效吗?答案是肯定的。通过使用分而治之的方法,类似于二分搜索中使用的方法,我们可以尝试以更有效的方式找到第 k 个元素。
  2. 比较数组 arr1 和 arr2 的中间元素,让我们分别称这些索引为 mid1 和 mid2。让我们假设 arr1[mid1] k,那么显然 mid2 之后的元素不能是所需的元素。将 arr2 的最后一个元素设置为 arr2[mid2]。
  3. 通过这种方式,定义一个新的子问题,其大小是其中一个数组的一半。

C++

// Program to find k-th element from two sorted arrays
#include 
using namespace std;
 
int kth(int *arr1, int *arr2, int *end1, int *end2, int k)
{
    if (arr1 == end1)
        return arr2[k];
    if (arr2 == end2)
        return arr1[k];
    int mid1 = (end1 - arr1) / 2;
    int mid2 = (end2 - arr2) / 2;
    if (mid1 + mid2 < k)
    {
        if (arr1[mid1] > arr2[mid2])
            return kth(arr1, arr2 + mid2 + 1, end1, end2,
                k - mid2 - 1);
        else
            return kth(arr1 + mid1 + 1, arr2, end1, end2,
                k - mid1 - 1);
    }
    else
    {
        if (arr1[mid1] > arr2[mid2])
            return kth(arr1, arr2, arr1 + mid1, end2, k);
        else
            return kth(arr1, arr2, end1, arr2 + mid2, k);
    }
}
 
int main()
{
    int arr1[5] = {2, 3, 6, 7, 9};
    int arr2[4] = {1, 4, 8, 10};
 
    int k = 5;
    cout << kth(arr1, arr2, arr1 + 5, arr2 + 4,  k - 1);
    return 0;
}

蟒蛇3

# Python program to find k-th element from two sorted arrays
def kth(arr1, arr2, n, m, k):
 
    if n == 1 or m == 1:
        if m == 1:
            arr2, arr1 = arr1, arr2
            m = n
        if k == 1:
            return min(arr1[0], arr2[0])
        elif k == m + 1:
            return max(arr1[0], arr2[0])
        else:
            if arr2[k - 1] < arr1[0]:
                return arr2[k - 1]
            else:
                return max(arr1[0], arr2[k - 2])
 
    mid1 = (n - 1)//2
    mid2 = (m - 1)//2
 
    if mid1+mid2+1 < k:
        if arr1[mid1] < arr2[mid2]:
            return kth(arr1[mid1 + 1:], arr2, n - mid1 - 1, m, k - mid1 - 1)
        else:
            return kth(arr1, arr2[mid2 + 1:], n, m - mid2 - 1, k - mid2 - 1)
    else:
        if arr1[mid1] < arr2[mid2]:
            return kth(arr1, arr2[:mid2 + 1], n, mid2 + 1, k)
        else:
            return kth(arr1[:mid1 + 1], arr2, mid1 + 1, m, k)
 
 
if __name__ == "__main__":
    arr1 = [2, 3, 6, 7, 9]
    arr2 = [1, 4, 8, 10]
    k = 5
    print(kth(arr1, arr2, 5, 4, k))
 
# This code is contributed by harshitkap00r
输出
6

请注意,在上面的代码中,k 是 0 索引的,这意味着如果我们希望 ak 是 1 索引,则在将其传递给函数时必须减去 1。
时间复杂度:O(log n + log m)

分而治之法2
虽然上述实现非常有效,但我们仍然可以使其更高效。不是将数组划分为 n / 2 和 m / 2 段然后递归,我们可以将它们同时除以 k / 2 和递归。下面的实现显示了这一点。

Explanation:
Instead of comparing the middle element of the arrays,
we compare the k / 2nd element.
Let arr1 and arr2 be the arrays.
Now, if arr1[k / 2]  arr1[1]

New subproblem:
Array 1 - 6 7 9
Array 2 - 1 4 8 10
k = 5 - 2 = 3

floor(k / 2) = 1
arr1[1] = 6
arr2[1] = 1
arr1[1] > arr2[1]

New subproblem:
Array 1 - 6 7 9
Array 2 - 4 8 10
k = 3 - 1 = 2

floor(k / 2) = 1
arr1[1] = 6
arr2[1] = 4
arr1[1] > arr2[1]

New subproblem:
Array 1 - 6 7 9
Array 2 - 8 10
k = 2 - 1 = 1

Now, we directly compare first elements,
since k = 1. 
arr1[1] < arr2[1]
Hence, arr1[1] = 6 is the answer.

C++

// C++ Program to find kth element from two sorted arrays
#include 
using namespace std;
 
int kth(int arr1[], int arr2[], int m, int n, int k,
                           int st1 = 0, int st2 = 0)
{
    // In case we have reached end of array 1
    if (st1 == m)
        return arr2[st2 + k - 1];
 
    // In case we have reached end of array 2
    if (st2 == n)
        return arr1[st1 + k - 1];
 
    // k should never reach 0 or exceed sizes
    // of arrays
    if (k == 0 || k > (m - st1) + (n - st2))
        return -1;
 
    // Compare first elements of arrays and return
    if (k == 1)
        return (arr1[st1] < arr2[st2]) ?
            arr1[st1] : arr2[st2];
    int curr = k / 2;
 
    // Size of array 1 is less than k / 2
    if (curr - 1 >= m - st1)
    {
        // Last element of array 1 is not kth
        // We can directly return the (k - m)th
        // element in array 2
        if (arr1[m - 1] < arr2[st2 + curr - 1])
            return arr2[st2 + (k - (m - st1) - 1)];
        else
            return kth(arr1, arr2, m, n, k - curr,
                st1, st2 + curr);
    }
 
    // Size of array 2 is less than k / 2
    if (curr-1 >= n-st2)
    {
        if (arr2[n - 1] < arr1[st1 + curr - 1])
            return arr1[st1 + (k - (n - st2) - 1)];
        else
            return kth(arr1, arr2, m, n, k - curr,
                st1 + curr, st2);
    }
    else
    {
        // Normal comparison, move starting index
        // of one array k / 2 to the right
        if (arr1[curr + st1 - 1] < arr2[curr + st2 - 1])
            return kth(arr1, arr2, m, n, k - curr,
                st1 + curr, st2);
        else
            return kth(arr1, arr2, m, n, k - curr,
                st1, st2 + curr);
    }
}
 
// Driver code
int main()
{
    int arr1[5] = {2, 3, 6, 7, 9};
    int arr2[4] = {1, 4, 8, 10};
 
    int k = 5;
    cout << kth(arr1, arr2, 5, 4,  k);
    return 0;
}

Java

// Java Program to find kth element from two sorted arrays
class GFG
{
 
    static int kth(int arr1[], int arr2[], int m,
                   int n, int k, int st1, int st2)
    {
        // In case we have reached end of array 1
        if (st1 == m)
        {
            return arr2[st2 + k - 1];
        }
 
        // In case we have reached end of array 2
        if (st2 == n)
        {
            return arr1[st1 + k - 1];
        }
 
        // k should never reach 0 or exceed sizes
        // of arrays
        if (k == 0 || k > (m - st1) + (n - st2))
        {
            return -1;
        }
 
        // Compare first elements of arrays and return
        if (k == 1)
        {
            return (arr1[st1] < arr2[st2])
                    ? arr1[st1] : arr2[st2];
        }
        int curr = k / 2;
 
        // Size of array 1 is less than k / 2
        if (curr - 1 >= m - st1)
        {
             
            // Last element of array 1 is not kth
            // We can directly return the (k - m)th
            // element in array 2
            if (arr1[m - 1] < arr2[st2 + curr - 1])
            {
                return arr2[st2 + (k - (m - st1) - 1)];
            }
            else
            {
                return kth(arr1, arr2, m, n, k - curr,
                        st1, st2 + curr);
            }
        }
 
        // Size of array 2 is less than k / 2
        if (curr - 1 >= n - st2)
        {
            if (arr2[n - 1] < arr1[st1 + curr - 1])
            {
                return arr1[st1 + (k - (n - st2) - 1)];
            }
            else
            {
                return kth(arr1, arr2, m, n, k - curr,
                        st1 + curr, st2);
            }
        }
        else
         
        // Normal comparison, move starting index
        // of one array k / 2 to the right
        if (arr1[curr + st1 - 1] < arr2[curr + st2 - 1])
        {
            return kth(arr1, arr2, m, n, k - curr,
                    st1 + curr, st2);
        }
        else
        {
            return kth(arr1, arr2, m, n, k - curr,
                    st1, st2 + curr);
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr1[] = {2, 3, 6, 7, 9};
        int arr2[] = {1, 4, 8, 10};
        int k = 5;
        int st1 = 0, st2 = 0;
        System.out.println(kth(arr1, arr2, 5, 4, k, st1, st2));
    }
}
 
// This code is contributed by 29AjayKumar

蟒蛇3

# Python3 program to find kth element from
# two sorted arrays
def kth(arr1, arr2, m, n, k, st1 = 0, st2 = 0):
     
    # In case we have reached end of array 1
    if (st1 == m):
        return arr2[st2 + k - 1]
 
    # In case we have reached end of array 2
    if (st2 == n):
        return arr1[st1 + k - 1]
 
    # k should never reach 0 or exceed sizes
    # of arrays
    if (k == 0 or k > (m - st1) + (n - st2)):
        return -1
         
    # Compare first elements of arrays and return
    if (k == 1):
        if(arr1[st1] < arr2[st2]):
            return arr1[st1]
        else:
            return arr2[st2]
 
    curr = int(k / 2)
 
    # Size of array 1 is less than k / 2
    if(curr - 1 >= m - st1):
 
        # Last element of array 1 is not kth
        # We can directly return the (k - m)th
        # element in array 2
        if (arr1[m - 1] < arr2[st2 + curr - 1]):
            return arr2[st2 + (k - (m - st1) - 1)]
        else:
            return kth(arr1, arr2, m, n,
                       k - curr, st1, st2 + curr)
 
    # Size of array 2 is less than k / 2
    if (curr - 1 >= n - st2):
        if (arr2[n - 1] < arr1[st1 + curr - 1]):
            return arr1[st1 + (k - (n - st2) - 1)]
        else:
            return kth(arr1, arr2, m, n,
                       k - curr,st1 + curr, st2)
    else:
         
        # Normal comparison, move starting index
        # of one array k / 2 to the right
        if (arr1[curr + st1 - 1] < arr2[curr + st2 - 1]):
            return kth(arr1, arr2, m, n, k - curr,
                       st1 + curr, st2)
        else:
            return kth(arr1, arr2, m, n, k - curr,
                       st1, st2 + curr)
 
# Driver code
arr1 = [ 2, 3, 6, 7, 9 ]
arr2 = [ 1, 4, 8, 10 ]
k = 5
 
print(kth(arr1, arr2, 5, 4, k))
 
# This code is contributed by avanitrachhadiya2155

C#

// C# Program to find kth element from two sorted arrays
using System;
 
class GFG
{
 
    static int kth(int []arr1, int []arr2, int m,
                int n, int k, int st1, int st2)
    {
        // In case we have reached end of array 1
        if (st1 == m)
        {
            return arr2[st2 + k - 1];
        }
 
        // In case we have reached end of array 2
        if (st2 == n)
        {
            return arr1[st1 + k - 1];
        }
 
        // k should never reach 0 or exceed sizes
        // of arrays
        if (k == 0 || k > (m - st1) + (n - st2))
        {
            return -1;
        }
 
        // Compare first elements of arrays and return
        if (k == 1)
        {
            return (arr1[st1] < arr2[st2])
                    ? arr1[st1] : arr2[st2];
        }
        int curr = k / 2;
 
        // Size of array 1 is less than k / 2
        if (curr - 1 >= m - st1)
        {
             
            // Last element of array 1 is not kth
            // We can directly return the (k - m)th
            // element in array 2
            if (arr1[m - 1] < arr2[st2 + curr - 1])
            {
                return arr2[st2 + (k - (m - st1) - 1)];
            }
            else
            {
                return kth(arr1, arr2, m, n, k - curr,
                        st1, st2 + curr);
            }
        }
 
        // Size of array 2 is less than k / 2
        if (curr - 1 >= n - st2)
        {
            if (arr2[n - 1] < arr1[st1 + curr - 1])
            {
                return arr1[st1 + (k - (n - st2) - 1)];
            }
            else
            {
                return kth(arr1, arr2, m, n, k - curr,
                        st1 + curr, st2);
            }
        }
        else
         
        // Normal comparison, move starting index
        // of one array k / 2 to the right
        if (arr1[curr + st1 - 1] < arr2[curr + st2 - 1])
        {
            return kth(arr1, arr2, m, n, k - curr,
                    st1 + curr, st2);
        }
        else
        {
            return kth(arr1, arr2, m, n, k - curr,
                    st1, st2 + curr);
        }
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int []arr1 = {2, 3, 6, 7, 9};
        int []arr2 = {1, 4, 8, 10};
        int k = 5;
        int st1 = 0, st2 = 0;
        Console.WriteLine(kth(arr1, arr2, 5, 4, k, st1, st2));
    }
}
 
// This code is contributed by PrinciRaj1992
输出
6

时间复杂度: O(log k)

现在,k 可以取最大值 m + n。这意味着在最坏的情况下,log k 可能是 log(m + n)。 Logm + logn = log(mn) 根据对数的性质,当 m, n > 2 时,log(m + n) < log(mn)。因此,该算法略微优于先前的算法。另外,请参阅Raj Kumar建议的另一种简单实现的 log k 方法

C++

// C++ Program to find kth
// element from two sorted arrays
// Time Complexity: O(log k)
 
#include 
using namespace std;
 
int kth(int arr1[], int m, int arr2[], int n, int k)
{
 
    if (k > (m + n) || k < 1)
        return -1;
 
    // let m <= n
    if (m > n)
        return kth(arr2, n, arr1, m, k);
 
    // Check if arr1 is empty returning
    // k-th element of arr2
    if (m == 0)
        return arr2[k - 1];
 
    // Check if k = 1 return minimum of
    // first two elements of both
    // arrays
    if (k == 1)
        return min(arr1[0], arr2[0]);
 
    // Now the divide and conquer part
    int i = min(m, k / 2), j = min(n, k / 2);
 
    if (arr1[i - 1] > arr2[j - 1])
       
        // Now we need to find only
        // k-j th element since we
        // have found out the lowest j
        return kth(arr1, m, arr2 + j, n - j, k - j);
    else
       
        // Now we need to find only
        // k-i th element since we
        // have found out the lowest i
        return kth(arr1 + i, m - i, arr2, n, k - i);
}
 
// Driver code
int main()
{
    int arr1[5] = { 2, 3, 6, 7, 9 };
    int arr2[4] = { 1, 4, 8, 10 };
    int m = sizeof(arr1) / sizeof(arr1[0]);
    int n = sizeof(arr2) / sizeof(arr2[0]);
    int k = 5;
 
    int ans = kth(arr1, m, arr2, n, k);
 
    if (ans == -1)
        cout << "Invalid query";
    else
        cout << ans;
 
    return 0;
}
// This code is contributed by Raj Kumar

Java

// Java Program to find kth element
// from two sorted arrays
// Time Complexity: O(log k)
import java.util.Arrays;
 
class Gfg {
    static int kth(int arr1[], int m, int arr2[], int n,
                   int k)
    {
        if (k > (m + n) || k < 1)
            return -1;
 
        // let m > n
        if (m > n)
            return kth(arr2, n, arr1, m, k);
 
        // Check if arr1 is empty returning
        // k-th element of arr2
        if (m == 0)
            return arr2[k - 1];
 
        // Check if k = 1 return minimum of first
        // two elements of both arrays
        if (k == 1)
            return Math.min(arr1[0], arr2[0]);
 
        // Now the divide and conquer part
        int i = Math.min(m, k / 2);
        int j = Math.min(n, k / 2);
 
        if (arr1[i - 1] > arr2[j - 1]) {
           
            // Now we need to find only k-j th element
            // since we have found out the lowest j
            int temp[] = Arrays.copyOfRange(arr2, j, n);
            return kth(arr1, m, temp, n - j, k - j);
        }
 
        // Now we need to find only k-i th element
        // since we have found out the lowest i
        int temp[] = Arrays.copyOfRange(arr1, i, m);
        return kth(temp, m - i, arr2, n, k - i);
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr1[] = { 2, 3, 6, 7, 9 };
        int arr2[] = { 1, 4, 8, 10 };
        int m = arr1.length;
        int n = arr2.length;
 
        int k = 5;
        int ans = kth(arr1, m, arr2, n, k);
        if (ans == -1)
            System.out.println("Invalid query");
        else
            System.out.println(ans);
    }
}
 
// This code is contributed by Vivek Kumar Singh
输出
6

时间复杂度: O(log k)

另一种方法:(使用最小堆)

  1. 将两个数组的元素推送到优先级队列(最小堆)。
  2. 从前面弹出 k-1 个元素。
  3. 优先级队列前面的元素是必需的答案。

下面是上述方法的实现:

C++

// C++ Program to find kth
// element from two sorted arrays
#include 
using namespace std;
 
// Function to find K-th min
int kth(int* a, int* b, int n, int m, int k)
{
      // Declaring a min heap
    priority_queue,
                   greater > pq;
       
      // Pushing elements for
    // array a to min-heap
    for (int i = 0; i < n; i++) {
        pq.push(a[i]);
    }
   
      // Pushing elements for
    // array b to min-heap
    for (int i = 0; i < m; i++) {
        pq.push(b[i]);
    }
   
      // Poping-out K-1 elements
    while (k-- > 1) {
        pq.pop();
    }
    return pq.top();
}
 
//Driver Code
int main()
{
    int arr1[5] = {2, 3, 6, 7, 9};
    int arr2[4] = {1, 4, 8, 10};
    int k = 5;
    cout << kth(arr1, arr2, 5, 4, k);
    return 0;
}
 
// This code is contributed by yashbeersingh42

Java

// Java Program to find kth element
// from two sorted arrays
import java.util.*;
 
class GFG {
   
    // Function to find K-th min
    static int kth(int a[], int b[],
                   int n, int m, int k)
    {
         
        // Declaring a min heap
        PriorityQueue pq =
                        new PriorityQueue<>();
 
        // Pushing elements for
        // array a to min-heap
        for (int i = 0; i < n; i++) {
            pq.offer(a[i]);
        }
 
        // Pushing elements for
        // array b to min-heap
        for (int i = 0; i < m; i++) {
            pq.offer(b[i]);
        }
 
        // Poping-out K-1 elements
        while (k-- > 1) {
            pq.remove();
        }
        return pq.peek();
    }
   
    // Driver Code
    public static void main(String[] args)
    {
        int arr1[] = { 2, 3, 6, 7, 9 };
        int arr2[] = { 1, 4, 8, 10 };
        int k = 5;
        System.out.print(kth(arr1, arr2, 5, 4, k));
    }
}
 
// This code is contributed by yashbeersingh42
输出
6

时间复杂度: O(NlogN)

空间复杂度: O(m+n)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程