📌  相关文章
📜  在数组中查找局部最小值

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

在数组中查找局部最小值

给定一个由不同整数组成的数组 arr[0 .. n-1],任务是在其中找到一个局部最小值。如果一个元素 arr[x] 小于它的两个邻居,我们就说它是一个局部最小值。

  • 对于角元素,我们只需要考虑一个邻居进行比较。
  • 一个数组中可以有多个局部最小值,我们需要找到其中一个。

例子:

Input: arr[] = {9, 6, 3, 14, 5, 7, 4};
Output: Index of local minima is 2
The output prints index of 3 because it is 
smaller than both of its neighbors. 
Note that indexes of elements 5 and 4 are 
also valid outputs.

Input: arr[] = {23, 8, 15, 2, 3};
Output: Index of local minima is 1

Input: arr[] = {1, 2, 3};
Output: Index of local minima is 0

Input: arr[] = {3, 2, 1};
Output: Index of local minima is 2

一个简单的解决方案是对数组进行线性扫描,一旦找到局部最小值,我们就返回它。该方法的最坏情况时间复杂度为 O(n)。
一个有效的解决方案是基于二分搜索。我们将中间元素与其邻居进行比较。如果中间元素不大于它的任何邻居,那么我们返回它。如果中间元素大于它的左邻居,那么左半边总是有一个局部最小值(为什么?举几个例子)。如果中间元素大于其右邻元素,则右半部分总是存在局部最小值(原因与左半部分相同)。
下面是上述想法的实现:

C++
// A C++ program to find a local minima in an array
#include 
 
// A binary search based function that returns
// index of a local minima.
int localMinUtil(int arr[], int low, int high, int n)
{
    // Find index of middle element
    int mid = low + (high - low)/2;  /* (low + high)/2 */
 
    // Compare middle element with its neighbours
    // (if neighbours exist)
    if ((mid == 0 || arr[mid-1] > arr[mid]) &&
            (mid == n-1 || arr[mid+1] > arr[mid]))
        return mid;
 
    // If middle element is not minima and its left
    // neighbour is smaller than it, then left half
    // must have a local minima.
    else if (mid > 0 && arr[mid-1] < arr[mid])
        return localMinUtil(arr, low, (mid -1), n);
 
    // If middle element is not minima and its right
    // neighbour is smaller than it, then right half
    // must have a local minima.
    return localMinUtil(arr, (mid + 1), high, n);
}
 
// A wrapper over recursive function localMinUtil()
int localMin(int arr[], int n)
{
    return localMinUtil(arr, 0, n-1, n);
}
 
/* Driver program to check above functions */
int main()
{
    int arr[] = {4, 3, 1, 14, 16, 40};
    int n = sizeof(arr)/sizeof(arr[0]);
    printf("Index of a local minima is %d",
                           localMin(arr, n));
    return 0;
}


Java
// A Java program to find a local minima in an array
import java.io.*;
 
class GFG
{
     
    // A binary search based function that returns
    // index of a local minima.
    public static int localMinUtil(int[] arr, int low,
                                   int high, int n)
    {
         
        // Find index of middle element
        int mid = low + (high - low) / 2;
         
         // Compare middle element with its neighbours
        // (if neighbours exist)
        if(mid == 0 || arr[mid - 1] > arr[mid] && mid == n - 1 ||
           arr[mid] < arr[mid + 1])
                return mid;
         
        // If middle element is not minima and its left
        // neighbour is smaller than it, then left half
        // must have a local minima.
        else if(mid > 0 && arr[mid - 1] < arr[mid])
                return localMinUtil(arr, low, mid - 1, n);
         
        // If middle element is not minima and its right
        // neighbour is smaller than it, then right half
        // must have a local minima.
        return localMinUtil(arr, mid + 1, high, n);
    }
     
    // A wrapper over recursive function localMinUtil()
    public static int localMin(int[] arr, int n)
    {
        return localMinUtil(arr, 0, n - 1, n);
    }
     
     
    public static void main (String[] args)
    {
         
        int arr[] = {4, 3, 1, 14, 16, 40};
        int n = arr.length;
        System.out.println("Index of a local minima is " + localMin(arr, n));
    
    }
}
 
//This code is contributed by Dheerendra Singh


Python3
# Python3 program to find a
# local minima in an array
 
# A binary search based function that
# returns index of a local minima.
def localMinUtil(arr, low, high, n):
         
    # Find index of middle element
    mid = low + (high - low) // 2 
         
    # Compare middle element with its
    # neighbours (if neighbours exist)
    if(mid == 0 or arr[mid - 1] > arr[mid] and
       mid == n - 1 or arr[mid] < arr[mid + 1]):
        return mid
         
    # If middle element is not minima and its left
    # neighbour is smaller than it, then left half
    # must have a local minima.
    elif(mid > 0 and arr[mid - 1] < arr[mid]):
        return localMinUtil(arr, low, mid - 1, n)
         
    # If middle element is not minima and its right
    # neighbour is smaller than it, then right half
    # must have a local minima.
    return localMinUtil(arr, mid + 1, high, n)
     
# A wrapper over recursive function localMinUtil()
def localMin(arr, n):
     
    return localMinUtil(arr, 0, n - 1, n)
     
# Driver code
arr = [4, 3, 1, 14, 16, 40]
n = len(arr)
print("Index of a local minima is " ,
                    localMin(arr, n))
                     
# This code is contributed by Anant Agarwal.


C#
// A C# program to find a
// local minima in an array
using System;
 
class GFG
{
     
    // A binary search based function that returns
    // index of a local minima.
    public static int localMinUtil(int[] arr, int low,
                                   int high, int n)
    {
         
        // Find index of middle element
        int mid = low + (high - low) / 2;
         
        // Compare middle element with its neighbours
        // (if neighbours exist)
        if(mid == 0 || arr[mid - 1] > arr[mid] &&
           mid == n - 1 || arr[mid] < arr[mid + 1])
                return mid;
         
        // If middle element is not minima and its left
        // neighbour is smaller than it, then left half
        // must have a local minima.
        else if(mid > 0 && arr[mid - 1] < arr[mid])
                return localMinUtil(arr, low, mid - 1, n);
         
        // If middle element is not minima and its right
        // neighbour is smaller than it, then right half
        // must have a local minima.
        return localMinUtil(arr, mid + 1, high, n);
    }
     
    // A wrapper over recursive function localMinUtil()
    public static int localMin(int[] arr, int n)
    {
        return localMinUtil(arr, 0, n - 1, n);
    }
     
    // Driver Code
    public static void Main ()
    {
         
        int []arr = {4, 3, 1, 14, 16, 40};
        int n = arr.Length;
        Console.WriteLine("Index of a local minima is " +
                            localMin(arr, n));
     
    }
}
 
// This code is contributed by vt_m.


PHP
 $arr[$mid]) and
        ($mid == $n - 1 or $arr[$mid + 1] > $arr[$mid]))
        return $mid;
 
    // If middle element is not
    // minima and its left
    // neighbour is smaller than
    // it, then left half
    // must have a local minima.
    else if ($mid > 0 and $arr[$mid - 1] < $arr[$mid])
        return localMinUtil($arr, $low, ($mid - 1), $n);
 
    // If middle element is not
    // minima and its right
    // neighbour is smaller than
    // it, then right half
    // must have a local minima.
    return localMinUtil(arr, (mid + 1), high, n);
}
 
// A wrapper over recursive
// function localMinUtil()
function localMin( $arr, $n)
{
    return floor(localMinUtil($arr, 0, $n - 1, $n));
}
 
    // Driver Code
    $arr = array(4, 3, 1, 14, 16, 40);
    $n = count($arr);
    echo "Index of a local minima is ",
                    localMin($arr, $n);
                     
// This code is contributed by anuj_67.
?>


输出:

Index of a local minima is 2