📌  相关文章
📜  在2D阵列中查找峰元素

📅  最后修改于: 2021-05-06 08:01:11             🧑  作者: Mango

如果一个元素大于或等于其四个相邻元素(左,右,上和下),则它是峰值元素。例如,A [i] [j]的邻居是A [i-1] [j],A [i + 1] [j],A [i] [j-1]和A [i] [j + 1] ]。对于拐角元素,丢失的邻居被认为是负无穷大。

例子:

Input : 10 20 15
        21 30 14
        7  16 32 
Output : 30
30 is a peak element because all its 
neighbors are smaller or equal to it. 
32 can also be picked as a peak.

Input : 10 7
        11 17
Output : 17

以下是有关此问题的一些事实:
1:对角线邻居不被视为邻居。
2:峰值元素不一定是最大元素。
3:可以存在多个这样的元素。
4:总有一个峰值元素。通过使用笔和纸创建一些矩阵,我们可以看到此属性。

方法1 :(强力)
遍历Matrix的所有元素,并检查它是否大于或等于其所有邻居。如果是,则返回该元素。

时间复杂度:O(行*列)
辅助空间:O(1)

方法2:(有效)
此问题主要是在1D数组中查找峰值元素的扩展。我们在此处应用类似的基于二进制搜索的解决方案。

  1. 考虑中间列并在其中找到最大元素。
  2. 假设中间列的索引为“ mid”,中间列的最大元素的值为“ max”,最大元素为“ mat [max_index] [mid]”。
  3. 如果max> = A [index] [mid-1]&max> = A [index] [pick + 1],则max为峰值,返回max。
  4. 如果max
  5. 如果max

下面是上述算法的实现:

C++
// Finding peak element in a 2D Array.
#include 
using namespace std;
  
const int MAX = 100;
  
// Function to find the maximum in column 'mid'
// 'rows' is number of rows.
int findMax(int arr[][MAX], int rows, int mid, int& max)
{
    int max_index = 0;
    for (int i = 0; i < rows; i++) {
        if (max < arr[i][mid]) {
            // Saving global maximum and its index
            // to check its neighbours
            max = arr[i][mid];
            max_index = i;
        }
    }
    return max_index;
}
  
// Function to find a peak element
int findPeakRec(int arr[][MAX], int rows, int columns,
                int mid)
{
    // Evaluating maximum of mid column. Note max is
    // passed by reference.
    int max = 0;
    int max_index = findMax(arr, rows, mid, max);
  
    // If we are on the first or last column,
    // max is a peak
    if (mid == 0 || mid == columns - 1)
        return max;
  
    // If mid column maximum is also peak
    if (max >= arr[max_index][mid - 1] && max >= arr[max_index][mid + 1])
        return max;
  
    // If max is less than its left
    if (max < arr[max_index][mid - 1])
        return findPeakRec(arr, rows, columns, mid - ceil((double)mid / 2));
  
    // If max is less than its left
    // if (max < arr[max_index][mid+1])
    return findPeakRec(arr, rows, columns, mid + ceil((double)mid / 2));
}
  
// A wrapper over findPeakRec()
int findPeak(int arr[][MAX], int rows, int columns)
{
    return findPeakRec(arr, rows, columns, columns / 2);
}
  
// Driver Code
int main()
{
    int arr[][MAX] = { { 10, 8, 10, 10 },
                       { 14, 13, 12, 11 },
                       { 15, 9, 11, 21 },
                       { 16, 17, 19, 20 } };
  
    // Number of Columns
    int rows = 4, columns = 4;
    cout << findPeak(arr, rows, columns);
    return 0;
}


Java
// Finding peak element in a 2D Array.
class GFG 
{
    static int MAX = 100;
  
    // Function to find the maximum in column 
    // 'mid', 'rows' is number of rows.
    static int findMax(int[][] arr, int rows, 
                       int mid, int max)
    {
        int max_index = 0;
        for (int i = 0; i < rows; i++)
        {
            if (max < arr[i][mid])
            {
                  
                // Saving global maximum and its index
                // to check its neighbours
                max = arr[i][mid];
                max_index = i;
            }
        }
        return max_index;
    }
  
    // Function to change the value of [max]
    static int Max(int[][] arr, int rows,
                   int mid, int max)
    {
        for (int i = 0; i < rows; i++)
        {
            if (max < arr[i][mid])
            {
                  
                // Saving global maximum and its index
                // to check its neighbours
                max = arr[i][mid];
            }
        }
        return max;
    }
  
    // Function to find a peak element
    static int findPeakRec(int[][] arr, int rows, 
                           int columns, int mid) 
    {
        // Evaluating maximum of mid column. 
        // Note max is passed by reference.
        int max = 0;
        int max_index = findMax(arr, rows, mid, max);
        max = Max(arr, rows, mid, max);
  
        // If we are on the first or last column,
        // max is a peak
        if (mid == 0 || mid == columns - 1)
            return max;
  
        // If mid column maximum is also peak
        if (max >= arr[max_index][mid - 1] && 
            max >= arr[max_index][mid + 1])
            return max;
  
        // If max is less than its left
        if (max < arr[max_index][mid - 1])
            return findPeakRec(arr, rows, columns, 
                         (int)(mid - Math.ceil((double) mid / 2)));
  
        // If max is less than its left
        // if (max < arr[max_index][mid+1])
        return findPeakRec(arr, rows, columns, 
                     (int)(mid + Math.ceil((double) mid / 2)));
    }
  
    // A wrapper over findPeakRec()
    static int findPeak(int[][] arr, int rows, int columns) 
    {
        return findPeakRec(arr, rows, columns, columns / 2);
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        int[][] arr = {{ 10, 8, 10, 10 },
                       { 14, 13, 12, 11 }, 
                       { 15, 9, 11, 21 }, 
                       { 16, 17, 19, 20 }};
          
        // Number of Columns
        int rows = 4, columns = 4;
        System.out.println(findPeak(arr, rows, columns));
    }
}
  
// This code is contributed by
// sanjeev2552


Python3
# Finding peak element in a 2D Array.
MAX = 100
from math import ceil
  
# Function to find the maximum in column 'mid'
# 'rows' is number of rows.
def findMax(arr, rows, mid,max):
  
    max_index = 0
    for i in range(rows):
        if (max < arr[i][mid]):
              
            # Saving global maximum and its index
            # to check its neighbours
            max = arr[i][mid]
            max_index = i
    #print(max_index)
  
    return max,max_index
  
# Function to find a peak element
def findPeakRec(arr, rows, columns,mid):
  
    # Evaluating maximum of mid column. 
    # Note max is passed by reference.
    max = 0
    max, max_index = findMax(arr, rows, mid, max)
  
    # If we are on the first or last column,
    # max is a peak
    if (mid == 0 or mid == columns - 1):
        return max
  
    # If mid column maximum is also peak
    if (max >= arr[max_index][mid - 1] and 
        max >= arr[max_index][mid + 1]):
        return max
  
    # If max is less than its left
    if (max < arr[max_index][mid - 1]):
        return findPeakRec(arr, rows, columns, 
                           mid - ceil(mid / 2.0))
  
    # If max is less than its left
    # if (max < arr[max_index][mid+1])
    return findPeakRec(arr, rows, columns, 
                       mid + ceil(mid / 2.0))
  
# A wrapper over findPeakRec()
def findPeak(arr, rows, columns):
    return findPeakRec(arr, rows, 
                       columns, columns // 2)
  
# Driver Code
arr = [ [ 10, 8, 10, 10 ],
        [ 14, 13, 12, 11 ],
        [ 15, 9, 11, 21 ],
        [ 16, 17, 19, 20 ] ]
  
# Number of Columns
rows = 4
columns = 4
print(findPeak(arr, rows, columns))
  
# This code is contributed by Mohit Kumar


C#
// Finding peak element in a 2D Array.
using System;
  
class GFG
{
  
    // Function to find the maximum in column 
    // 'mid', 'rows' is number of rows.
    static int findMax(int[,] arr, int rows, 
                       int mid, int max)
    {
        int max_index = 0;
        for (int i = 0; i < rows; i++)
        {
            if (max < arr[i,mid])
            {
                  
                // Saving global maximum and its 
                // index to check its neighbours
                max = arr[i,mid];
                max_index = i;
            }
        }
        return max_index;
    }
  
    // Function to change the value of [max]
    static int Max(int[,] arr, int rows,
                   int mid, int max)
    {
        for (int i = 0; i < rows; i++)
        {
            if (max < arr[i, mid])
            {
                  
                // Saving global maximum and its 
                // index to check its neighbours
                max = arr[i, mid];
            }
        }
        return max;
    }
  
    // Function to find a peak element
    static int findPeakRec(int[,] arr, int rows, 
                           int columns, int mid) 
    {
        // Evaluating maximum of mid column. 
        // Note max is passed by reference.
        int max = 0;
        int max_index = findMax(arr, rows, mid, max);
        max = Max(arr, rows, mid, max);
  
        // If we are on the first or last column,
        // max is a peak
        if (mid == 0 || mid == columns - 1)
            return max;
  
        // If mid column maximum is also peak
        if (max >= arr[max_index, mid - 1] && 
            max >= arr[max_index, mid + 1])
            return max;
  
        // If max is less than its left
        if (max < arr[max_index,mid - 1])
            return findPeakRec(arr, rows, columns, 
                   (int)(mid - Math.Ceiling((double) mid / 2)));
  
        // If max is less than its left
        // if (max < arr[max_index][mid+1])
        return findPeakRec(arr, rows, columns, 
               (int)(mid + Math.Ceiling((double) mid / 2)));
    }
  
    // A wrapper over findPeakRec()
    static int findPeak(int[,] arr, 
                        int rows, int columns) 
    {
        return findPeakRec(arr, rows, columns, 
                                      columns / 2);
    }
  
    // Driver Code
    static public void Main ()
    {
        int[,] arr = {{ 10, 8, 10, 10 },
                      { 14, 13, 12, 11 }, 
                      { 15, 9, 11, 21 }, 
                      { 16, 17, 19, 20 }};
      
        // Number of Columns
        int rows = 4, columns = 4;
        Console.Write(findPeak(arr, rows, columns));
    }
}
  
// This code is contributed by ajit.


输出:

21

时间复杂度:O(行*对数(列))。我们重复进行一半的列数。在每个递归调用中,我们线性搜索当前中间列中的最大值。

辅助空间:O(columns / 2)用于递归调用堆栈

来源:
https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-2011/lecture-videos/MIT6_006F11_lec01.pdf