问题引入

给定一个数组arr,其中 arr[i] != arr[i+1],找到唯一峰值元素并返回其索引

首先,定位到题干中的关键字:峰值元素
峰值元素是指 其值大于左右相邻值 的元素,是数组的一个转折点。

法一:循环遍历

根据峰值元素的特性,可以直接遍历找到符合条件的峰值元素:

思想:
遍历数组,如果当前元素大于它相邻的元素,则输出它的索引。
若当前数组只有一个元素,则输出0,若当前元素为首尾元素,则只需要大于其另一侧的元素即可。

//js
let arr = [3,4,5,6,7,1,2];
let index = 0;if (arr.length !== 1)  {// 遍历判断第二个元素~倒数第二个元素for (let i = 1; i < arr.length-1; i++) {if (arr[i-1] < arr[i] && arr[i] > arr[i+1]) {index = i;break;}}// 如果上述未找到峰值,则峰值为最后一个元素(整个数组全部升序排列)if (index === 0) index = arr.length-1;
}
console.log(index);

上述代码的时间复杂度为O(n),在执行数据量小的数组当然没问题,但是如果我们要找一个数据量大的数组呢?

法二:二分查找

这个时候我们就应该想到二分法来进行优化,最后的时间复杂度可变为O(logn)

实现二分查找方法之前,我们先来了解一个常识:
在当一个人爬山,先上山再下山,目的地为山最高的点(山峰)
若我们知道 i+1 和 i 值的大小关系 ,就可推断这个人是在山峰的左边还是右边

  • 当i+1值 > i值,人在山峰的左边(上坡路)

  • 当 i+1值 < i值,人在山峰的右边(下坡路)

这道题的核心思想就是如此。

二分实现:

设置两个指针,left指向第一个元素,right指向最后一个元素,mid指向中间元素。

如果mid-1指向的元素小于mid指向的元素 => mid之后可能存在最大值,left = mid;
如果mid指向的元素大于mid+1指向的元素 => mid之前存在最大值,right=mid。

直到mid指向的元素大于mid+1和mid-1指向的元素时,停止.

图解

  1. left=0,right = 6,middle = (0+6)/ 2=3
    arr[middle-1]=5 < arr[middle]=6
    => middle左边都是升序值,所以峰值必定在middle右边,将左边界位置设为middle+1=4
    此时截取右边的子数组:
  2. left=4,right = 6,middle = (4+6)/ 2=5
    arr[middle-1]=7 < arr[middle]=1
    => 说明峰值在middle左边,将右边界位置设为middle=5
    截取左边子数组:
  3. left=4,right = 5,middle = (4+5)/ 2=4
    arr[middle]满足大于相邻元素的值,说明此时已找到峰值7,索引为4
function half() {let left = 0;let right = arr.length;// 如果数组长度为1,则峰值索引为0if (right === 1) {return 0;}while (left < right) {let middle = parseInt((left+right)/2);// 如果middle大于相邻元素,返回middle,表示已找到if (arr[middle] > arr[middle+1] && arr[middle] > arr[middle-1]) {return middle;}if (arr[middle] < arr[middle-1]) {// 若middle<middle-1值,说明峰值在middle左边,将middle设为右边界right = middle;} else {// 若middle>middle-1值,说明峰值在middle右边,将middle+1设为左边界left = middle+1;}}return left;
}

二分实现:查找数组中的峰值元素相关推荐

  1. 查找数组中的指定元素的位置--顺序查找与二分查找

    Java代码-查找数组中的指定元素的位置 /*** 查找数组中指定元素(顺序查找)*/ class Demo6 {public static void main(String[] args) {int ...

  2. 查找数组中任一峰值的下标

    查找数组中任一峰值的下标 如题所示: 思路 源代码如下: 如题所示: 峰值元素是指其值大于左右相邻值的元素. 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返 ...

  3. Java-Runoob-高级教程-实例-数组:10. Java 实例 – 查找数组中的重复元素-un

    ylbtech-Java-Runoob-高级教程-实例-数组:10. Java 实例 – 查找数组中的重复元素 1.返回顶部 1. Java 实例 - 查找数组中的重复元素  Java 实例 以下实例 ...

  4. php 查找数组相同元素,查找数组中重复的元素

    本文收集整理关于查找数组中重复的元素的相关议题,使用内容导航快速到达. 内容导航: Q1:在c语言中输入数组两个数组,查找重复元素并输出怎么写啊 可以一次读入N个数据.可以考虑以回车结束读入的一组. ...

  5. Java实例-查找数组中的重复元素

    代码实现 public class MainClass {public static void main(String[] args) {int[] my_array = {1, 2, 5, 5, 6 ...

  6. c语言在数组中找最小数,C语言 查找数组中最大最小元素

    //findMax.c /** 查找数组中最大,最小的元素. */ #include #include #include void main() { int array[10];// int Y=10 ...

  7. 查找数组中重复的元素

    数组a共n+1个元素,元素取值范围1~n,返回数组中重复的元素之一 题目条件限定了数组中一定有重复元素,可以对每个可能的取值1~n计算出现次数.或者划分取值范围为1~m,m+1~n,计算两个取值区间在 ...

  8. 查找数组中的重复元素

    //数组根据定义的类型进行修改,public static void findDuplicateNum(Integer[] arr) {int count = 0;for (int i = 0; i ...

  9. js查找数组中符合条件的元素

    js查找数组中符合条件元素的几种方法 一.利用for循环进行查找 let arr = [{name: 'zhangsan', age: 18},{name: 'lisi', age: 17},{nam ...

最新文章

  1. 9月热文精选,为你的假期加点料
  2. matlab数据无量纲化_MATLAB数据预处理——归一化和标准化
  3. 《人潮汹涌》的观后感
  4. 阿里打造全球首个纯机器人送货高校,22个物流机器人进入浙大备战双11
  5. DBMS_SPACE包的使用
  6. IDEA2020版本如何导入jar包
  7. mysql 堆叠查询_SQL 注入方法 - 盲注、报错注入、UNION查询注入与堆叠注入
  8. 2021年3月15日_读书|总结笔记目录
  9. opencv_modules.hpp 头文件
  10. 欧式理论计算机科学,理论计算机科学中几个问题.ppt
  11. 下拉默认选择_在Excel中制作二级联动下拉菜单,太有用了
  12. 爱卡创誓记java饰品,《创誓记AIKA》芙兰精灵配上框架眼睛折服宅男宅女
  13. rtmp rtsp 区别_鱼胶粉和吉利丁粉的区别
  14. 孙鑫VC学习笔记:第十七讲 (二) 用匿名管道实现进程间的通信
  15. 贝叶斯网络结构学习方法简介
  16. SAP中常用SE系列TCODE汇总
  17. centos7系统开启ftp服务器,centos7开启ftp服务器
  18. 淘宝客网站SEO及赚钱与揭密
  19. @Value注入静态变量(static)
  20. R语言lowess函数数据平滑实战(Locally Weighted Regression, Loess)

热门文章

  1. 专业App开发:设计App图标的三个关键点
  2. ES6新语法--箭头函数
  3. 一分钟实现纯CSS全屏滚动特效
  4. 网页中、英文安全字体选择及设置
  5. Ubuntu 16.04 LTS与windows双系统时间同步解决方法
  6. 7-3 方格取数 (15 分)
  7. 4006基于邻接矩阵的顶点的删除(C++,附思路)
  8. 基于顺序存储结构的图书信息表的逆序存储(C++)
  9. vivado中如何读取十进制小数_二进制十进制间小数怎么转换,原来是这样的
  10. java集成hibernate_JavaWeb_(Spring框架)Spring整合Hibernate