给定一个大小为N的排序数组arr[]和一个整数K ,任务是找到数组中存在的第K个最小元素。给定的阵列已经通过反转子阵列获得{ARR [0],ARR [R]}和{ARR [R + 1],ARR [N – 1]}在一些随机指数R.如果该键不存在于数组,打印-1 。
例子:
Input: arr[] = { 4, 3, 2, 1, 8, 7, 6, 5 }, K = 2
Output: 2
Explanation: Sorted form of the array arr[] is { 1, 2, 3, 4, 5, 6, 7, 8 }. Therefore, the 2nd smallest element in the array arr[] is 2.
Input: arr[] = { 10, 8, 6, 5, 2, 1, 13, 12 }, K = 3
Output: 5
朴素的方法:解决问题最简单的方法是将给定的数组arr[]按升序排序并打印数组中第K个最小的元素。
时间复杂度: O(N*log(N))
辅助空间: O(1)
上述解决方案的替代方法:我们可以在不使用任何排序技术的情况下对数组进行排序,这肯定会降低时间复杂度。我们可以使用二分搜索找到数组中的枢轴点P (旋转发生在它周围) ,然后使用std::reverse()函数反转两个子数组[0, P + 1]和[P + 1, N]在 C++ 中。
反转子数组:找到枢轴点P 后,只需找到两个子数组的反转如下:
std::reverse(arr, arr + P + 1);
std::reverse(arr + P + 1, arr + N);
因此我们得到了排序后的数组,我们可以将第 K 个最小元素打印为arr[K-1] 。
C++
// C++ program for the above approach.
#include
using namespace std;
/* Function to get pivot. For array 4, 3, 2, 1, 6, 5
it returns 3 (index of 1) */
int findPivot(int arr[], int low, int high)
{
// base cases
if (high < low)
return -1;
if (high == low)
return low;
int mid = (low + high) / 2; /*low + (high - low)/2;*/
if (mid < high && arr[mid] < arr[mid + 1])
return mid;
if (mid > low && arr[mid] > arr[mid - 1])
return (mid - 1);
if (arr[low] <= arr[mid])
return findPivot(arr, low, mid - 1);
return findPivot(arr, mid + 1, high);
}
// Driver Code
int main()
{
// Given Input
int arr[] = { 10, 8, 6, 5, 2, 1, 13, 12 };
int N = sizeof(arr) / sizeof(arr[0]);
int K = 3;
// Function Call
int P = findPivot(arr, 0, N - 1);
// reversing first subarray
reverse(arr, arr + P + 1);
// reversing second subarray
reverse(arr + P + 1, arr + N);
// printing output
cout << arr[K - 1];
return 0;
}
// This code is contributed by Pranjay Vats
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the Kth element in a
// sorted and rotated array at random point
int findkthElement(vector arr, int n, int K)
{
// Set the boundaries for binary search
int l = 0;
int h = n - 1, r;
// Apply binary search to find R
while (l + 1 < h)
{
// Initialize the middle element
int mid = (l + h) / 2;
// Check in the right side of mid
if (arr[l] >= arr[mid])
l = mid;
// Else check in the left side
else
h = mid;
}
// Random point either l or h
if (arr[l] < arr[h])
r = l;
else
r = h;
// Return the kth smallest element
if (K <= r + 1)
return arr[r + 1 - K];
else
return arr[n - (K - (r + 1))];
}
// Driver Code
int main()
{
// Given Input
vector arr = { 10, 8, 6, 5, 2, 1, 13, 12 };
int n = arr.size();
int K = 3;
// Function Call
cout << findkthElement(arr, n, K);
}
// This code is contributed by mohit kumar 29
Java
// Java program for the above approach
class GFG{
// Function to find the Kth element in a
// sorted and rotated array at random point
public static int findkthElement(int arr[], int n, int K)
{
// Set the boundaries for binary search
int l = 0;
int h = n - 1, r;
// Apply binary search to find R
while (l + 1 < h)
{
// Initialize the middle element
int mid = (l + h) / 2;
// Check in the right side of mid
if (arr[l] >= arr[mid])
l = mid;
// Else check in the left side
else
h = mid;
}
// Random point either l or h
if (arr[l] < arr[h])
r = l;
else
r = h;
// Return the kth smallest element
if (K <= r + 1)
return arr[r + 1 - K];
else
return arr[n - (K - (r + 1))];
}
// Driver Code
public static void main(String args[])
{
// Given Input
int []arr = { 10, 8, 6, 5, 2, 1, 13, 12 };
int n = arr.length;
int K = 3;
// Function Call
System.out.println(findkthElement(arr, n, K));
}
}
// This code is contributed by SoumikMondal
Python3
# Python program for the above approach
# Function to find the Kth element in a
# sorted and rotated array at random point
def findkthElement(arr, n, K):
# Set the boundaries for binary search
l = 0
h = n-1
# Apply binary search to find R
while l+1 < h:
# Initialize the middle element
mid = (l+h)//2
# Check in the right side of mid
if arr[l] >= arr[mid]:
l = mid
# Else check in the left side
else:
h = mid
# Random point either l or h
if arr[l] < arr[h]:
r = l
else:
r = h
# Return the kth smallest element
if K <= r+1:
return arr[r+1-K]
else:
return arr[n-(K-(r+1))]
# Driver Code
if __name__ == "__main__":
# Given Input
arr = [10, 8, 6, 5, 2, 1, 13, 12]
n = len(arr)
K = 3
# Function Call
print(findkthElement(arr, n, K) )
C#
using System.IO;
using System;
class GFG {
// Function to find the Kth element in a
// sorted and rotated array at random point
public static int findkthElement(int[] arr, int n,
int K)
{
// Set the boundaries for binary search
int l = 0;
int h = n - 1, r;
// Apply binary search to find R
while (l + 1 < h) {
// Initialize the middle element
int mid = (l + h) / 2;
// Check in the right side of mid
if (arr[l] >= arr[mid])
l = mid;
// Else check in the left side
else
h = mid;
}
// Random point either l or h
if (arr[l] < arr[h])
r = l;
else
r = h;
// Return the kth smallest element
if (K <= r + 1)
return arr[r + 1 - K];
else
return arr[n - (K - (r + 1))];
}
static void Main()
{
// Given Input
int[] arr = { 10, 8, 6, 5, 2, 1, 13, 12 };
int n = arr.Length;
int K = 3;
// Function Call
Console.WriteLine(findkthElement(arr, n, K));
}
}
// This code is contributed by abhinavjain194.
Javascript
5
时间复杂度: O(N)
辅助空间: O(1)
高效的方法:最优的想法是基于观察到第R 个元素是最小的元素,因为[1, R]范围内的元素是颠倒的。现在,如果随机索引为R ,则表示子数组[1, R]和[R + 1, N]按降序排序。因此,任务减少到找到可以使用二分搜索获得的R的值。最后,打印第K个最小元素。
请按照以下步骤解决问题:
- 将l初始化为1 ,将h初始化为N,以存储二分搜索的搜索空间的边界元素索引。
- 循环而l+1 < h的值
- 将中间元素存储在一个变量中, mid为(l+h)/2 。
- 如果arr[l] ≥ arr[mid]。如果这是真的,然后通过更新l至中期检查中旬的右侧。
- 否则,将r更新为mid 。
- 现在在找到R 之后,如果K ≤ R ,那么答案是arr[R-K+1]。否则, arr[N-(KR)+1] 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the Kth element in a
// sorted and rotated array at random point
int findkthElement(vector arr, int n, int K)
{
// Set the boundaries for binary search
int l = 0;
int h = n - 1, r;
// Apply binary search to find R
while (l + 1 < h)
{
// Initialize the middle element
int mid = (l + h) / 2;
// Check in the right side of mid
if (arr[l] >= arr[mid])
l = mid;
// Else check in the left side
else
h = mid;
}
// Random point either l or h
if (arr[l] < arr[h])
r = l;
else
r = h;
// Return the kth smallest element
if (K <= r + 1)
return arr[r + 1 - K];
else
return arr[n - (K - (r + 1))];
}
// Driver Code
int main()
{
// Given Input
vector arr = { 10, 8, 6, 5, 2, 1, 13, 12 };
int n = arr.size();
int K = 3;
// Function Call
cout << findkthElement(arr, n, K);
}
// This code is contributed by mohit kumar 29
Java
// Java program for the above approach
class GFG{
// Function to find the Kth element in a
// sorted and rotated array at random point
public static int findkthElement(int arr[], int n, int K)
{
// Set the boundaries for binary search
int l = 0;
int h = n - 1, r;
// Apply binary search to find R
while (l + 1 < h)
{
// Initialize the middle element
int mid = (l + h) / 2;
// Check in the right side of mid
if (arr[l] >= arr[mid])
l = mid;
// Else check in the left side
else
h = mid;
}
// Random point either l or h
if (arr[l] < arr[h])
r = l;
else
r = h;
// Return the kth smallest element
if (K <= r + 1)
return arr[r + 1 - K];
else
return arr[n - (K - (r + 1))];
}
// Driver Code
public static void main(String args[])
{
// Given Input
int []arr = { 10, 8, 6, 5, 2, 1, 13, 12 };
int n = arr.length;
int K = 3;
// Function Call
System.out.println(findkthElement(arr, n, K));
}
}
// This code is contributed by SoumikMondal
蟒蛇3
# Python program for the above approach
# Function to find the Kth element in a
# sorted and rotated array at random point
def findkthElement(arr, n, K):
# Set the boundaries for binary search
l = 0
h = n-1
# Apply binary search to find R
while l+1 < h:
# Initialize the middle element
mid = (l+h)//2
# Check in the right side of mid
if arr[l] >= arr[mid]:
l = mid
# Else check in the left side
else:
h = mid
# Random point either l or h
if arr[l] < arr[h]:
r = l
else:
r = h
# Return the kth smallest element
if K <= r+1:
return arr[r+1-K]
else:
return arr[n-(K-(r+1))]
# Driver Code
if __name__ == "__main__":
# Given Input
arr = [10, 8, 6, 5, 2, 1, 13, 12]
n = len(arr)
K = 3
# Function Call
print(findkthElement(arr, n, K) )
C#
using System.IO;
using System;
class GFG {
// Function to find the Kth element in a
// sorted and rotated array at random point
public static int findkthElement(int[] arr, int n,
int K)
{
// Set the boundaries for binary search
int l = 0;
int h = n - 1, r;
// Apply binary search to find R
while (l + 1 < h) {
// Initialize the middle element
int mid = (l + h) / 2;
// Check in the right side of mid
if (arr[l] >= arr[mid])
l = mid;
// Else check in the left side
else
h = mid;
}
// Random point either l or h
if (arr[l] < arr[h])
r = l;
else
r = h;
// Return the kth smallest element
if (K <= r + 1)
return arr[r + 1 - K];
else
return arr[n - (K - (r + 1))];
}
static void Main()
{
// Given Input
int[] arr = { 10, 8, 6, 5, 2, 1, 13, 12 };
int n = arr.Length;
int K = 3;
// Function Call
Console.WriteLine(findkthElement(arr, n, K));
}
}
// This code is contributed by abhinavjain194.
Javascript
5
时间复杂度: O(log(N))
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。