给定一个山形数组arr []和一个整数X ,任务是在给定数组中找到X的最小索引。如果找不到这样的索引,则打印-1 。
例子:
Input: arr = {1, 2, 3, 4, 5, 3, 1}, X = 3
Output: 2
Explanation:
The smallest index of X(= 3) in the array is 2.
Therefore, the required output is 2.
Input: arr[] = {0, 1, 2, 4, 2, 1}, X = 3
Output: -1
Explanation: Since 3 does not exist in the array, the required output is -1.
天真的方法:最简单的方法是遍历数组并检查当前索引处的元素是否等于X。如果发现为真,则打印该索引。
时间复杂度: O(N)
辅助空间: O(1)
高效的方法:解决此问题的最佳方法是使用二进制搜索。请按照以下步骤解决此问题:
- 从山峰阵列中找到峰指数。
- 根据获得的峰值索引,将分区阵列分为两部分,首先使用二进制搜索在其左侧搜索,然后使用右侧搜索。已知峰值元素的左侧以升序排序,而右侧以降序排序。
- 在左侧的山阵中搜索。
下面是上述方法的实现:
C++
// CPP program for the above approach
#include
using namespace std;
// Function to find the index of
// the peak element in the array
int findPeak(vector arr)
{
// Stores left most index in which
// the peak element can be found
int left = 0;
// Stores right most index in which
// the peak element can be found
int right = arr.size() - 1;
while (left < right)
{
// Stores mid of left and right
int mid = left + (right - left) / 2;
// If element at mid is less than
// element at (mid + 1)
if (arr[mid] < arr[mid + 1])
{
// Update left
left = mid + 1;
}
else
{
// Update right
right = mid;
}
}
return left;
}
// Function to perform binary search in an
// a subarray if elements of the subarray
// are in an ascending order
int BS(int X, int left, int right,
vector arr)
{
while (left <= right)
{
// Stores mid of left and right
int mid = left + (right - left) / 2;
// If X found at mid
if (arr[mid] == X)
{
return mid;
}
// If X is greater than mid
else if (X > arr[mid])
{
// Update left
left = mid + 1;
}
else
{
// Update right
right = mid - 1;
}
}
return -1;
}
// Function to perform binary search in an
// a subarray if elements of the subarray
// are in an ascending order
int reverseBS(int X, int left, int right, vector arr)
{
while (left <= right)
{
// Stores mid of left and right
int mid = left + (right - left) / 2;
// If X found at mid
if (arr[mid] == X)
{
return mid;
}
else if (X > arr[mid])
{
// Update right
right = mid - 1;
}
else
{
// Update left
left = mid + 1;
}
}
return -1;
}
// Function to find the smallest index of X
void findInMA(int X, vector mountainArr)
{
// Stores index of peak element in array
int peakIndex = findPeak(mountainArr);
// Stores index of X in the array
int res = -1;
// If X greater than or equal to first element
// of array and less than the peak element
if (X >= mountainArr[0] && X <= mountainArr[peakIndex])
{
// Update res
res = BS(X, 0, peakIndex, mountainArr);
}
// If element not found on
// left side of peak element
if (res == -1)
{
// Update res
res = reverseBS(X, peakIndex + 1,
mountainArr.size() - 1,
mountainArr);
}
// Print res
cout< list{1, 2, 3, 4, 5, 3, 1};
// Function Call
findInMA(X, list);
}
// This code is contributed by bgangwar59.
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to find the index of
// the peak element in the array
public static int findPeak(
ArrayList arr)
{
// Stores left most index in which
// the peak element can be found
int left = 0;
// Stores right most index in which
// the peak element can be found
int right = arr.size() - 1;
while (left < right) {
// Stores mid of left and right
int mid = left + (right - left) / 2;
// If element at mid is less than
// element at (mid + 1)
if (arr.get(mid) < arr.get(mid + 1)) {
// Update left
left = mid + 1;
}
else {
// Update right
right = mid;
}
}
return left;
}
// Function to perform binary search in an
// a subarray if elements of the subarray
// are in an ascending order
static int BS(int X, int left, int right,
ArrayList arr)
{
while (left <= right) {
// Stores mid of left and right
int mid = left + (right - left) / 2;
// If X found at mid
if (arr.get(mid) == X) {
return mid;
}
// If X is greater than mid
else if (X > arr.get(mid)) {
// Update left
left = mid + 1;
}
else {
// Update right
right = mid - 1;
}
}
return -1;
}
// Function to perform binary search in an
// a subarray if elements of the subarray
// are in an ascending order
static int reverseBS(int X, int left, int right,
ArrayList arr)
{
while (left <= right) {
// Stores mid of left and right
int mid = left + (right - left) / 2;
// If X found at mid
if (arr.get(mid) == X) {
return mid;
}
else if (X > arr.get(mid)) {
// Update right
right = mid - 1;
}
else {
// Update left
left = mid + 1;
}
}
return -1;
}
// Function to find the smallest index of X
static void findInMA(int X,
ArrayList mountainArr)
{
// Stores index of peak element in array
int peakIndex = findPeak(mountainArr);
// Stores index of X in the array
int res = -1;
// If X greater than or equal to first element
// of array and less than the peak element
if (X >= mountainArr.get(0)
&& X <= mountainArr.get(peakIndex)) {
// Update res
res = BS(X, 0, peakIndex, mountainArr);
}
// If element not found on
// left side of peak element
if (res == -1) {
// Update res
res = reverseBS(X, peakIndex + 1,
mountainArr.size() - 1,
mountainArr);
}
// Print res
System.out.println(res);
}
// Driver Code
public static void main(String[] args)
{
// Given X
int X = 3;
// Given array
ArrayList list = new ArrayList<>(
Arrays.asList(1, 2, 3, 4, 5, 3, 1));
// Function Call
findInMA(X, list);
}
}
Python3
# Python3 program for the above approach
# Function to find the index of
# the peak element in the array
def findPeak(arr):
# Stores left most index in which
# the peak element can be found
left = 0
# Stores right most index in which
# the peak element can be found
right = len(arr) - 1
while (left < right):
# Stores mid of left and right
mid = left + (right - left) // 2
# If element at mid is less than
# element at(mid + 1)
if (arr[mid] < arr[(mid + 1)]):
# Update left
left = mid + 1
else:
# Update right
right = mid
return left
# Function to perform binary search in an
# a subarray if elements of the subarray
# are in an ascending order
def BS(X, left, right, arr):
while (left <= right):
# Stores mid of left and right
mid = left + (right - left) // 2
# If X found at mid
if (arr[mid] == X):
return mid
# If X is greater than mid
elif (X > arr[mid]):
# Update left
left = mid + 1
else:
# Update right
right = mid - 1
return -1
# Function to perform binary search in an
# a subarray if elements of the subarray
# are in an ascending order
def reverseBS(X, left, right, arr):
while (left <= right):
# Stores mid of left and right
mid = left + (right - left) // 2
# If X found at mid
if (arr[mid] == X):
return mid
elif (X > arr[mid]):
# Update right
right = mid - 1
else:
# Update left
left = mid + 1
return -1
# Function to find the smallest index of X
def findInMA(X, mountainArr):
# Stores index of peak element in array
peakIndex = findPeak(mountainArr)
# Stores index of X in the array
res = -1
# If X greater than or equal to first element
# of array and less than the peak element
if (X >= mountainArr[0] and
X <= mountainArr[peakIndex]):
# Update res
res = BS(X, 0, peakIndex, mountainArr)
# If element not found on
# left side of peak element
if (res == -1):
# Update res
res = reverseBS(X, peakIndex + 1,
mountainArr.size() - 1,
mountainArr)
# Print res
print(res)
# Driver Code
if __name__ == "__main__":
# Given X
X = 3
# Given array
arr = [ 1, 2, 3, 4, 5, 3, 1 ]
# Function Call
findInMA(X, arr)
# This code is contributed by chitranayal
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{
// Function to find the index of
// the peak element in the array
public static int findPeak(List arr)
{
// Stores left most index in which
// the peak element can be found
int left = 0;
// Stores right most index in which
// the peak element can be found
int right = arr.Count - 1;
while (left < right)
{
// Stores mid of left and right
int mid = left + (right - left) / 2;
// If element at mid is less than
// element at (mid + 1)
if (arr[mid] < arr[(mid + 1)])
{
// Update left
left = mid + 1;
}
else
{
// Update right
right = mid;
}
}
return left;
}
// Function to perform binary search in an
// a subarray if elements of the subarray
// are in an ascending order
static int BS(int X, int left, int right,
List arr)
{
while (left <= right)
{
// Stores mid of left and right
int mid = left + (right - left) / 2;
// If X found at mid
if (arr[(mid)] == X)
{
return mid;
}
// If X is greater than mid
else if (X > arr[mid])
{
// Update left
left = mid + 1;
}
else
{
// Update right
right = mid - 1;
}
}
return -1;
}
// Function to perform binary search in an
// a subarray if elements of the subarray
// are in an ascending order
static int reverseBS(int X, int left, int right,
List arr)
{
while (left <= right)
{
// Stores mid of left and right
int mid = left + (right - left) / 2;
// If X found at mid
if (arr[mid] == X)
{
return mid;
}
else if (X > arr[mid])
{
// Update right
right = mid - 1;
}
else
{
// Update left
left = mid + 1;
}
}
return -1;
}
// Function to find the smallest index of X
static void findInMA(int X,
List mountainArr)
{
// Stores index of peak element in array
int peakIndex = findPeak(mountainArr);
// Stores index of X in the array
int res = -1;
// If X greater than or equal to first element
// of array and less than the peak element
if (X >= mountainArr[0]
&& X <= mountainArr[peakIndex])
{
// Update res
res = BS(X, 0, peakIndex, mountainArr);
}
// If element not found on
// left side of peak element
if (res == -1)
{
// Update res
res = reverseBS(X, peakIndex + 1,
mountainArr.Count - 1,
mountainArr);
}
// Print res
Console.WriteLine(res);
}
// Driver Code
public static void Main( )
{
// Given X
int X = 3;
// Given array
List list = new List(){1, 2, 3, 4, 5, 3, 1};
// Function Call
findInMA(X, list);
}
}
// This code is contributed by code_hunt.
输出:
2
时间复杂度: O(Log(N))
辅助空间: O(1)