📌  相关文章
📜  在Mountain数组中搜索元素

📅  最后修改于: 2021-05-17 02:43:17             🧑  作者: Mango

给定一个山形数组arr []和一个整数X ,任务是在给定数组中找到X的最小索引。如果找不到这样的索引,则打印-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)