📌  相关文章
📜  通过从随机索引反转子数组形成的排序数组中的第 K 个最小元素

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

给定一个大小为N的排序数组arr[]和一个整数K ,任务是找到数组中存在的K最小元素。给定的阵列已经通过反转子阵列获得{ARR [0],ARR [R]}{ARR [R + 1],ARR [N – 1]}在一些随机指数R.如果该不存在于数组,打印-1

例子:

朴素的方法:解决问题最简单的方法是将给定的数组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 现场工作专业课程学生竞争性编程现场课程