📜  使用二分搜索算法重新排列数组以找到 K,无需排序

📅  最后修改于: 2022-05-13 01:56:05.399000             🧑  作者: Mango

使用二分搜索算法重新排列数组以找到 K,无需排序

给定一个包含N个不同整数的数组arr[]和一个整数K ,任务是以这样一种方式重新排列给定的数组,使得可以借助二分搜索算法在重新排列的数组中找到K。请注意,该数组不进行排序。

例子:

方法:可以根据以下观察解决给定的问题:

请按照以下步骤解决问题:

  • 初始化一个数组,比如ans[] ,所有数组元素都为-1以存储重新排列的数组。
  • 此外,初始化两个向量,表示小于大于K 以存储小于和大于K的元素。
  • 遍历数组arr[]并在当前元素小于K时将其推入较小的值。否则,如果它大于K ,则将其推入更大
  • 在数组arr[]中找到元素K的索引,然后将其值分配给K
  • 初始化两个变量,比如0N-1 ,以执行二分搜索。
  • 迭代直到low小于或等于high并执行以下步骤:
    • 找到当前范围的中间值[low, high]并将其存储在一个变量中,比如mid
    • 如果mid小于K ,则执行以下操作:
      • 如果small.size()0 ,则打印“ -1 ”并返回。
      • 否则,将向量的最后一个元素更小分配给ans[mid] ,然后弹出更小的最后一个元素。
    • 如果mid大于K ,则执行以下操作:
      • 如果greater.size()0 ,则打印“ -1 ”并返回。
      • 否则,将向量的最后一个元素更大,分配给ans[mid] ,然后弹出更大的最后一个元素。
    • 如果mid等于K ,则将arr[K]分配给ans[mid]然后中断。
  • 完成上述步骤后,遍历数组ans[] ,如果当前元素为“ -1 ”即未填充,则为其分配任何未使用的元素。
  • 最后,将数组ans[]打印为重新排列的数组。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to rearrange the array
void Rearrange(int arr[], int K, int N)
{
    // Stores the rearranged array
    int ans[N + 1];
 
    // Stores whether the arrangement
    // is possible or not
    int f = -1;
 
    for (int i = 0; i < N; i++) {
        ans[i] = -1;
    }
 
    // Update K with the position of K
    K = find(arr, arr + N, K) - arr;
    
    // Stores all elements lesser than
    // and greater than in vector smaller
    // and greater respectively
    vector smaller, greater;
 
    // Traverse the array arr[]
    for (int i = 0; i < N; i++) {
 
        // If arr[i] is less than arr[K]
        if (arr[i] < arr[K])
            smaller.push_back(arr[i]);
 
        // Else
        else if (arr[i] > arr[K])
            greater.push_back(arr[i]);
    }
 
    int low = 0, high = N - 1;
 
    // Iterate until low is less than or
    // equal to high
    while (low <= high) {
 
        // Stores mid point
        int mid = (low + high) / 2;
 
        // If mid is equal to K
        if (mid == K) {
            ans[mid] = arr[K];
            f = 1;
            break;
        }
 
        // If mid is less than K
        else if (mid < K) {
            if (smaller.size() == 0) {
                break;
            }
            ans[mid] = smaller.back();
            smaller.pop_back();
            low = mid + 1;
        }
        // If mid is greater than K
        else {
            if (greater.size() == 0) {
                break;
            }
            ans[mid] = greater.back();
            greater.pop_back();
            high = mid - 1;
        }
    }
 
    // If f is -1
    if (f == -1) {
        cout << -1 << endl;
        return;
    }
 
    // Iterate in the range [1, N]
    for (int i = 0; i < N; i++) {
 
        // If ans[i] is equal to -1
        if (ans[i] == -1) {
 
            if (smaller.size()) {
                ans[i] = smaller.back();
                smaller.pop_back();
            }
            else if (greater.size()) {
                ans[i] = greater.back();
                greater.pop_back();
            }
        }
    }
 
    // Print the rearranged array
    for (int i = 0; i < N; i++)
        cout << ans[i] << " ";
    cout << endl;
}
 
// Driver Code
int main()
{
    // Input
    int arr[] = { 10, 7, 2, 5, 3, 8 };
    int K = 7;
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    Rearrange(arr, K, N);
 
    return 0;
}


Java
// Java program for the above approach
  
import java.util.*;
public class GFG
{
   
// Function to rearrange the array
static void Rearrange(int arr[], int K, int N)
{
   
    // Stores the rearranged array
    int ans[] = new int[N + 1];
 
    // Stores whether the arrangement
    // is possible or not
    int f = -1;
 
    for (int i = 0; i < N; i++) {
        ans[i] = -1;
    }
 
    // Update K with the position of K
   for (int i = 0; i < arr.length; i++)
   {
       if (arr[i] == K)
       {
           K = i;
           break;
       }
   }
    
    // Stores all elements lesser than
    // and greater than in vector smaller
    // and greater respectively
     Vector smaller = new Vector();
     Vector greater = new Vector();
      
    // Traverse the array arr[]
    for (int i = 0; i < N; i++) {
 
        // If arr[i] is less than arr[K]
        if (arr[i] < arr[K])
            smaller.add(arr[i]);
 
        // Else
        else if (arr[i] > arr[K])
            greater.add(arr[i]);
    }
 
    int low = 0, high = N - 1;
 
    // Iterate until low is less than or
    // equal to high
    while (low <= high) {
 
        // Stores mid point
        int mid = (low + high) / 2;
 
        // If mid is equal to K
        if (mid == K) {
            ans[mid] = arr[K];
            f = 1;
            break;
        }
 
        // If mid is less than K
        else if (mid < K) {
            if (smaller.size() == 0) {
                break;
            }
            ans[mid] = smaller.lastElement();
            smaller.remove(smaller.size()-1);
            low = mid + 1;
        }
       
        // If mid is greater than K
        else {
            if (greater.size() == 0) {
                break;
            }
            ans[mid] = greater.lastElement();
            greater.remove(greater.size()-1);
            high = mid - 1;
        }
    }
 
    // If f is -1
    if (f == -1) {
        System.out.println(-1 );
        return;
    }
 
    // Iterate in the range [1, N]
    for (int i = 0; i < N; i++) {
 
        // If ans[i] is equal to -1
        if (ans[i] == -1) {
 
            if (smaller.size()>0) {
                ans[i] = smaller.lastElement();
                smaller.remove(smaller.size()-1);
            }
            else if (greater.size()>0) {
                ans[i] = greater.lastElement();
                greater.remove(greater.size()-1);
            }
        }
    }
 
    // Print the rearranged array
    for (int i = 0; i < N; i++)
        System.out.print(ans[i] +" ");
    System.out.println();
}
   
  // Driver code
    public static void main(String args[])
    {
       
      // Input
    int arr[] = { 10, 7, 2, 5, 3, 8 };
    int K = 7;
    int N = arr.length;
 
    // Function Call
    Rearrange(arr, K, N);
    }
}
 
// This code is contributed by SoumikMondal


Python3
# Python 3 program for the above approach
 
 
# Function to rearrange the array
def Rearrange(arr, K,  N):
 
    # Stores the rearranged array
    ans = [0]*(N + 1)
 
    # Stores whether the arrangement
    # is possible or not
    f = -1
 
    for i in range(N):
        ans[i] = -1
 
    # Update K with the position of K
    K = arr.index(K)
 
    # Stores all elements lesser than
    # and greater than in vector smaller
    # and greater respectively
    smaller = []
    greater = []
 
    # Traverse the array arr[]
    for i in range(N):
 
        # If arr[i] is less than arr[K]
        if (arr[i] < arr[K]):
            smaller.append(arr[i])
 
        # Else
        elif (arr[i] > arr[K]):
            greater.append(arr[i])
 
    low = 0
    high = N - 1
 
    # Iterate until low is less than or
    # equal to high
    while (low <= high):
 
        # Stores mid point
        mid = (low + high) // 2
 
        # If mid is equal to K
        if (mid == K):
            ans[mid] = arr[K]
            f = 1
            break
 
        # If mid is less than K
        elif (mid < K):
            if (len(smaller) == 0):
                break
 
            ans[mid] = smaller[-1]
            smaller.pop()
            low = mid + 1
 
        # If mid is greater than K
        else:
            if (len(greater) == 0):
                break
 
            ans[mid] = greater[-1]
            greater.pop()
            high = mid - 1
 
    # If f is -1
    if (f == -1):
        print(-1)
        return
 
    # Iterate in the range [1, N]
    for i in range(N):
 
        # If ans[i] is equal to -1
        if (ans[i] == -1):
 
            if (len(smaller)):
                ans[i] = smaller[-1]
                smaller.pop()
 
            elif (len(greater)):
                ans[i] = greater[-1]
                greater.pop()
 
    # Print the rearranged array
    for i in range(N):
        print(ans[i], end=" ")
    print()
 
 
# Driver Code
if __name__ == "__main__":
 
    # Input
    arr = [10, 7, 2, 5, 3, 8]
    K = 7
    N = len(arr)
 
    # Function Call
    Rearrange(arr, K, N)
 
    # This code is contributed by ukasp.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG
{
 
  // Function to rearrange the array
  static void Rearrange(int []arr, int K, int N)
  {
 
    // Stores the rearranged array
    int []ans = new int[N + 1];
 
    // Stores whether the arrangement
    // is possible or not
    int f = -1;
 
    for (int i = 0; i < N; i++) {
      ans[i] = -1;
    }
 
    // Update K with the position of K
    for (int i = 0; i < arr.Length; i++)
    {
      if (arr[i] == K)
      {
        K = i;
        break;
      }
    }
 
    // Stores all elements lesser than
    // and greater than in vector smaller
    // and greater respectively
    List smaller = new List();
    List greater = new List();
 
    // Traverse the array []arr
    for (int i = 0; i < N; i++) {
 
      // If arr[i] is less than arr[K]
      if (arr[i] < arr[K])
        smaller.Add(arr[i]);
 
      // Else
      else if (arr[i] > arr[K])
        greater.Add(arr[i]);
    }
 
    int low = 0, high = N - 1;
 
    // Iterate until low is less than or
    // equal to high
    while (low <= high) {
 
      // Stores mid point
      int mid = (low + high) / 2;
 
      // If mid is equal to K
      if (mid == K) {
        ans[mid] = arr[K];
        f = 1;
        break;
      }
 
      // If mid is less than K
      else if (mid < K) {
        if (smaller.Count == 0) {
          break;
        }
        ans[mid] = smaller[smaller.Count-1];
        smaller.RemoveAt(smaller.Count-1);
        low = mid + 1;
      }
 
      // If mid is greater than K
      else {
        if (greater.Count == 0) {
          break;
        }
        ans[mid] = greater[greater.Count-1];
        greater.RemoveAt(greater.Count-1);
        high = mid - 1;
      }
    }
 
    // If f is -1
    if (f == -1) {
      Console.WriteLine(-1 );
      return;
    }
 
    // Iterate in the range [1, N]
    for (int i = 0; i < N; i++) {
 
      // If ans[i] is equal to -1
      if (ans[i] == -1) {
 
        if (smaller.Count>0) {
          ans[i] = smaller[smaller.Count-1];
          smaller.RemoveAt(smaller.Count-1);
        }
        else if (greater.Count>0) {
          ans[i] = greater[greater.Count-1];
          greater.RemoveAt(greater.Count-1);
        }
      }
    }
 
    // Print the rearranged array
    for (int i = 0; i < N; i++)
      Console.Write(ans[i] +" ");
    Console.WriteLine();
  }
 
  // Driver code
  public static void Main(String []args)
  {
 
    // Input
    int []arr = { 10, 7, 2, 5, 3, 8 };
    int K = 7;
    int N = arr.Length;
 
    // Function Call
    Rearrange(arr, K, N);
  }
}
 
 
// This code is contributed by Princi Singh


Javascript


输出
3 7 8 5 2 10 

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