给定两个大小分别为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
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;
}
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));
}
}
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
输出
6
时间复杂度: O(k)
辅助空间: O(1)
- 分而治之的方法1
虽然先前的方法有效,但是我们可以使我们的算法更有效吗?答案是肯定的。通过使用分治法,类似于二进制搜索中使用的方法,我们可以尝试以更有效的方式找到第k个元素。 - 比较数组arr1和arr2的中间元素,让我们分别将这些索引称为mid1和mid2。让我们假设arr1 [mid1] k,那么显然mid2之后的元素不能成为必需的元素。将arr2的最后一个元素设置为arr2 [mid2]。
- 这样,用一个数组的一半大小定义一个新的子问题。
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;
}
输出
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
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
输出
6
时间复杂度: O(log k)
现在,k可以取m + n的最大值。这意味着log k在最坏的情况下可能是log(m + n)。 Logm + logn = log(mn),取对数属性,当m,n> 2时,log(m + n)
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)
另一种方法:(使用Min Heap)
- 将两个数组的元素推入优先级队列(最小堆)。
- 从前面弹出k-1个元素。
- 优先级队列前面的元素是必需的答案。
下面是上述方法的实现:
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)