📜  在双音数组中查找一个元素

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

在双音数组中查找一个元素

给定一个包含n 个不同元素的双调序列和一个整数x ,任务是编写一个程序在O(log n)时间内在双调序列中找到给定的元素x

例子:

天真的方法:一个简单的解决方案是进行线性搜索。该解决方案的时间复杂度为 O(n)。

有效方法:一种有效的解决方案是基于二分搜索。

以下是有关如何执行此操作的分步算法。

  1. 找到给定数组中的双调点,即给定双调数组中的最大元素。这可以通过修改二进制搜索算法在 log(n) 时间内完成。你可以参考这篇文章来了解如何做到这一点。
  2. 如果要搜索的元素等于双调点处的元素,则打印双调点的索引。
  3. 如果要搜索的元素大于双调点处的元素,则该元素不存在于数组中。
  4. 如果要搜索的元素小于双调点处的元素,则使用二分搜索在数组的两半中搜索元素。

下面是上述思想的实现:

C++
// C++ code to search key in bitonic array
#include 
 
using namespace std;
 
// Function for binary search in ascending part
int ascendingBinarySearch(int arr[], int low,
                        int high, int key)
{
    while (low <= high)
    {
        int mid = low + (high - low) / 2;
        if (arr[mid] == key)
            return mid;
        if (arr[mid] > key)
            high = mid - 1;
        else
            low = mid + 1;
    }
    return -1;
}
 
// Function for binary search in
// descending part of array
int descendingBinarySearch(int arr[], int low,
                        int high, int key)
{
    while (low <= high)
    {
        int mid = low + (high - low) / 2;
        if (arr[mid] == key)
            return mid;
        if (arr[mid] < key)
            high = mid - 1;
        else
            low = mid + 1;
    }
    return -1;
}
 
// finding bitonic point
int findBitonicPoint(int arr[], int n,
                    int l, int r)
{
    int mid;
    int bitonicPoint = 0;
    mid = (r + l) / 2;
    if (arr[mid] > arr[mid - 1]
        && arr[mid] > arr[mid + 1])
    {
        return mid;
    }
 
    else if (arr[mid] > arr[mid - 1]
            && arr[mid] < arr[mid + 1])
    {
        bitonicPoint = findBitonicPoint(arr, n, mid, r);
    }
 
    else if (arr[mid] < arr[mid - 1]
            && arr[mid] > arr[mid + 1])
    {
        bitonicPoint = findBitonicPoint(arr, n, l, mid);
    }
    return bitonicPoint;
}
 
// Function to search key in
// bitonic array
int searchBitonic(int arr[], int n,
                int key, int index)
{
    if (key > arr[index])
        return -1;
 
    else if (key == arr[index])
        return index;
 
    else {
        int temp
            = ascendingBinarySearch(arr,
                                    0, index - 1,
                                    key);
        if (temp != -1) {
            return temp;
        }
 
        // Search in right of k
        return descendingBinarySearch(arr,
                                    index + 1,
                                    n - 1,
                                    key);
    }
}
 
// Driver code
int main()
{
    int arr[] = { -8, 1, 2, 3, 4, 5, -2, -3 };
    int key = 1;
    int n, l, r;
    n = sizeof(arr) / sizeof(arr[0]);
    l = 0;
    r = n - 1;
    int index;
 
    // Function call
    index = findBitonicPoint(arr, n, l, r);
 
    int x = searchBitonic(arr, n, key, index);
 
    if (x == -1)
        cout << "Element Not Found" << endl;
    else
        cout << "Element Found at index " << x << endl;
 
    return 0;
}


Java
// Java code to search key in bitonic array
public class GFG {
 
    // Function for binary search
    // in ascending part
    static int ascendingBinarySearch(int arr[],
                                    int low,
                                    int high,
                                    int key)
    {
        while (low <= high)
        {
            int mid = low + (high - low) / 2;
            if (arr[mid] == key)
            {
                return mid;
            }
            if (arr[mid] > key)
            {
                high = mid - 1;
            }
            else
            {
                low = mid + 1;
            }
        }
        return -1;
    }
 
    // Function for binary search in
    // descending part of array
    static int descendingBinarySearch(int arr[],
                                    int low,
                                    int high,
                                    int key)
    {
        while (low <= high)
        {
            int mid = low + (high - low) / 2;
            if (arr[mid] == key)
            {
                return mid;
            }
            if (arr[mid] < key)
            {
                high = mid - 1;
            }
            else
            {
                low = mid + 1;
            }
        }
        return -1;
    }
 
    // finding bitonic point
    static int findBitonicPoint(int arr[],
                                int n,
                                int l,
                                int r)
    {
        int mid;
        int bitonicPoint = 0;
        mid = (r + l) / 2;
        if (arr[mid] > arr[mid - 1]
            && arr[mid] > arr[mid + 1])
        {
            return mid;
        }
        else {
            if (arr[mid] > arr[mid - 1]
                && arr[mid] < arr[mid + 1])
            {
                bitonicPoint = findBitonicPoint(arr, n, mid, r);
            }
            else {
                if (arr[mid] < arr[mid - 1]
                    && arr[mid] > arr[mid + 1])
                {
                    bitonicPoint = findBitonicPoint(arr, n, l, mid);
                }
            }
        }
        return bitonicPoint;
    }
 
    // Function to search key in bitonic array
    static int searchBitonic(int arr[], int n,
                            int key, int index)
    {
        if (key > arr[index])
        {
            return -1;
        }
        else if (key == arr[index])
        {
            return index;
        }
        else {
            int temp = ascendingBinarySearch(
                arr, 0, index - 1, key);
            if (temp != -1)
            {
                return temp;
            }
 
            // Search in right of k
            return descendingBinarySearch(arr, index + 1,
                                        n - 1, key);
        }
    }
 
    // Driver code
    public static void main(String args[])
    {
        int arr[] = { -8, 1, 2, 3, 4, 5, -2, -3 };
        int key = 5;
        int n, l, r;
        n = arr.length;
        l = 0;
        r = n - 1;
        int index;
        index = findBitonicPoint(arr, n, l, r);
 
        int x = searchBitonic(arr, n, key, index);
 
        if (x == -1) {
            System.out.println("Element Not Found");
        }
        else {
            System.out.println("Element Found at index "
                            + x);
        }
    }
}
 
/*This code is contributed by 29AjayKumar*/


Python3
# Python code to search key in bitonic array
 
# Function for binary search in ascending part
def ascendingBinarySearch(arr, low, high, key):
     
    while low <= high:
        mid = low + (high - low) // 2
         
        if arr[mid] == key:
            return mid
         
        if arr[mid] > key:
            high = mid - 1
        else:
            low = mid + 1
             
    return -1
 
# Function for binary search in descending part of array
def descendingBinarySearch(arr, low, high, key):
     
    while low <= high:
        mid = low + (high - low) // 2
         
        if arr[mid] == key:
            return mid
         
        if arr[mid] < key:
            high = mid - 1
        else:
            low = mid + 1
             
    return -1
 
# Find bitonic point
def findBitonicPoint(arr, n, l, r):
     
    bitonicPoint = 0
    mid = (r + l) // 2
     
    if arr[mid] > arr[mid-1] and arr[mid] > arr[mid+1]:
        return mid
     
    elif arr[mid] > arr[mid-1] and arr[mid] < arr[mid+1]:
        bitonicPoint = findBitonicPoint(arr, n, mid, r)
    else:
        bitonicPoint = finsBitonicPoint(arr, n, l, mid)
         
    return bitonicPoint
 
# Function to search key in bitonic array
def searchBitonic(arr, n, key, index):
     
    if key > arr[index]:
        return -1
    elif key == arr[index]:
        return index
    else:
        temp = ascendingBinarySearch(arr, 0, index-1, key)
        if temp != -1:
            return temp
         
        # search in right of k
        return descendingBinarySearch(arr, index+1, n-1, key)
     
# Driver code
def main():
    arr = [-8, 1, 2, 3, 4, 5, -2, -3]
    key = 1
    n = len(arr)
    l = 0
    r = n - 1
     
    # Function call
    index = findBitonicPoint(arr, n, l, r)
     
    x = searchBitonic(arr, n, key, index)
     
    if x == -1:
        print("Element Not Found")
    else:
        print("Element Found at index", x)
         
main()
 
# This code is contributed by stutipathak31jan


C#
// C# code to search key in bitonic array
using System;
 
class GFG {
    // Function for binary search in ascending part
    static int ascendingBinarySearch(int[] arr, int low,
                                    int high, int key)
    {
        while (low <= high)
        {
            int mid = low + (high - low) / 2;
            if (arr[mid] == key)
            {
                return mid;
            }
            if (arr[mid] > key)
            {
                high = mid - 1;
            }
            else {
                low = mid + 1;
            }
        }
        return -1;
    }
 
    // Function for binary search in descending part of
    // array
    static int descendingBinarySearch(int[] arr, int low,
                                    int high, int key)
    {
        while (low <= high)
        {
            int mid = low + (high - low) / 2;
            if (arr[mid] == key)
            {
                return mid;
            }
            if (arr[mid] < key)
            {
                high = mid - 1;
            }
            else
            {
                low = mid + 1;
            }
        }
        return -1;
    }
 
    // finding bitonic point
    static int findBitonicPoint(int[] arr, int n, int l,
                                int r)
    {
        int mid;
        int bitonicPoint = 0;
        mid = (r + l) / 2;
        if (arr[mid] > arr[mid - 1]
            && arr[mid] > arr[mid + 1])
        {
            return mid;
        }
        else
        {
            if (arr[mid] > arr[mid - 1]
                && arr[mid] < arr[mid + 1]) {
                bitonicPoint = findBitonicPoint(arr, n, mid, r);
            }
            else
            {
                if (arr[mid] < arr[mid - 1]
                    && arr[mid] > arr[mid + 1]) {
                    bitonicPoint = findBitonicPoint(arr, n, l, mid);
                }
            }
        }
        return bitonicPoint;
    }
 
    // Function to search key in bitonic array
    static int searchBitonic(int[] arr, int n, int key,
                            int index)
    {
        if (key > arr[index])
        {
            return -1;
        }
        else if (key == arr[index])
        {
            return index;
        }
        else {
            int temp = ascendingBinarySearch(
                arr, 0, index - 1, key);
            if (temp != -1) {
                return temp;
            }
 
            // Search in right of k
            return descendingBinarySearch(arr, index + 1,
                                        n - 1, key);
        }
    }
 
    // Driver Code
    static public void Main()
    {
        int[] arr = { -8, 1, 2, 3, 4, 5, -2, -3 };
        int key = 1;
        int n, l, r;
        n = arr.Length;
        l = 0;
        r = n - 1;
        int index;
        index = findBitonicPoint(arr, n, l, r);
 
        int x = searchBitonic(arr, n, key, index);
 
        if (x == -1) {
            Console.WriteLine("Element Not Found");
        }
        else {
            Console.WriteLine("Element Found at index "
                            + x);
        }
    }
}
 
// This code is contributed by ajit


Javascript


输出
Element Found at index 1

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