数组中的峰值元素

时间:2014-12-07 20:58:25

标签: arrays algorithm binary-search

所以我试图解决以下问题:

  

给定一个整数数组。找到其中的峰值元素。如果数组元素不小于其邻居,则它是峰值。对于角落元素,我们只需要考虑一个邻居。例如,对于输入数组{5,10,20,15},20是唯一的峰值元素。对于输入数组{10,20,15,2,23,90,67},有两个峰值元素:20和90.请注意,我们需要返回任何一个峰值元素。

来自以下链接:http://www.geeksforgeeks.org/find-a-peak-in-a-given-array/

他们曾经说过

  

如果中间元素小于其左邻居,则左半部分始终存在峰值。

此时我感到困惑,我们怎么知道左半部分会有一个峰值元素?我可以从中得出结论,至少有一个元素肯定比它的右邻居(即[m-1])大,所以它有机会它可以我已经研究过stackoverflow和其他网站但是找不到上述结论的好解释

感谢您的帮助!

4 个答案:

答案 0 :(得分:3)

假设您站在比其左邻居低的中间元素上:

            element
                         you
                       element

你向左看。它看起来像一座小山。

假设你爬上那座山。你看到了什么?嗯,有三种可能性:

1.
  element
              you
            element

                       element

2.
              you
  element   element

                       element

3.
              you
            element

  element              element

在案例2和3中,万岁!你找到了一个高峰。在案例1中,你继续攀登。最后,要么你看到一个不高于你的元素,要么你看到左墙。在任何一种情况下,您都找到了一个高峰。

答案 1 :(得分:2)

这句话很重要:

  

对于角落元素,我们只需要考虑一个邻居。

让我们看看当您从中间元素向左迭代时会发生什么。我们知道左边的那个更大。如果左边的那个小或相等,那么你找到了一个峰值。如果没有,请递归。

递归有两种可能性:要么你最终找到一个峰值,要么到达终点。如果你到达终点,那么最后的元素是你到目前为止找到的最大元素,因此它是角元素定义的峰值。

答案 2 :(得分:0)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

/**
 * @author asharda
 *
 */
public class Peak {

  public int findPeakElement(int[] nums) {

    Integer[] num = new Integer[nums.length];
    for (int i = 0; i < nums.length; i++) {
      num[i] = Integer.valueOf(nums[i]);
    }
    ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(num));
    Collections.sort(list);
    int peak = list.get(list.size() - 1);
    int top = 0;
    for (int i = 0; i < nums.length - 1; i++) {
      if (nums[i] == peak) {
        top = i;
      }
    }

    return top;
  }

  public static void main(String[] args) {

    int nums[] = {1, 2, 1, 3, 5, 6, 4};
    Peak p = new Peak();
    System.out.println(p.findPeakElement(nums));

  }

}

答案 3 :(得分:0)

假设nums [mid]

package main

import (
    "encoding/json"
    "fmt"
    "reflect"
)

type PolicyDocument struct {
    Version   string
    Statement []StatementEntry
}

type StatementEntry struct {
    Effect   string
    Action   []string
    Resource interface{}
}

func main() {

    data := `{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ssm:PutParameter",
                "ssm:DeleteParameter",
                "ssm:DescribeInstancePatchStates",
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:DescribeTargetHealth",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DeregisterTargets",
                "ssm:GetParameter"
            ],
            "Resource": "*"
        }
    ]
}`

    convertPolicy(data)

    data = `{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::SageMaker"
            ]
        },
        {
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::SageMaker/*"
            ]
        }
    ]
}`

    convertPolicy(data)

}

func convertPolicy(data string) {
    var doc PolicyDocument
    err1 := json.Unmarshal([]byte(data), &doc)

    if err1 != nil {
        fmt.Println(err1)
    }

    //find out the type of resource string or []string
    for _, statement := range doc.Statement {
        fmt.Println("statement.Resource was of type - ", reflect.TypeOf(statement.Resource))
        if reflect.TypeOf(statement.Resource).Name() != "string" {
            // we will convert the []interface to []string
            x := statement.Resource.([]interface{})
            y := make([]string, len(x))
            for i := 0; i < len(x); i++ {
                y[i] = x[i].(string)
            }
            statement.Resource = y
            fmt.Println("statement.Resource is converted to type - ", reflect.TypeOf(statement.Resource))
        }
    }

    fmt.Printf("\n----\n%v\n---\n", doc)
}

-无穷大必须来自上方,因为我们可以说nums [0]和nums [nums.size()-1]是有限的。

因此,我们可以清楚地看到右侧可能有峰值,也可能没有,请考虑当右侧严格降低而没有峰值的情况。

在左侧:如果nums [mid-2]                           -Infinity和nums [0]是有限的,因此您得到了峰值。