在双音数组中查找一个元素
给定一个包含n 个不同元素的双调序列和一个整数x ,任务是编写一个程序在O(log n)时间内在双调序列中找到给定的元素x 。
A Bitonic Sequence is a sequence of numbers that is first strictly increasing then after a point decreasing.
例子:
Input : arr[] = {-3, 9, 18, 20, 17, 5, 1}, key = 20
Output : Found at index 3
Input : arr[] = {5, 6, 7, 8, 9, 10, 3, 2, 1}, key = 30
Output : Not Found
天真的方法:一个简单的解决方案是进行线性搜索。该解决方案的时间复杂度为 O(n)。
有效方法:一种有效的解决方案是基于二分搜索。
- The idea is to find the bitonic point ‘k’ which is the index of the maximum element of a given sequence.
- If the element to be searched is greater than the maximum element return -1,
- else search the element in both halves.
以下是有关如何执行此操作的分步算法。
- 找到给定数组中的双调点,即给定双调数组中的最大元素。这可以通过修改二进制搜索算法在 log(n) 时间内完成。你可以参考这篇文章来了解如何做到这一点。
- 如果要搜索的元素等于双调点处的元素,则打印双调点的索引。
- 如果要搜索的元素大于双调点处的元素,则该元素不存在于数组中。
- 如果要搜索的元素小于双调点处的元素,则使用二分搜索在数组的两半中搜索元素。
下面是上述思想的实现:
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)