问题引入

给定一个数组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. ArcGIS Server for Silverlight 之集群(Simple Clusterer)
  2. Volley学习总结
  3. 在.NET中调用存储过程
  4. C++ 学习笔记----基础篇
  5. Spring配置redis(自定义方法)
  6. Flex4_操作XML
  7. RHEL7及CentOS7的语言、字符编码、键盘映射、X11布局设置(localectl)-系统管理(1)...
  8. 引用原话,不等于原意
  9. markdown日常
  10. VC2013同一个工程生成的exe文件显示不同的图标
  11. Excel取消合并单元格时在每个单元格中保留内容,你会批量操作吗?
  12. 怎样去掉Using default security password:2A70F900-4445-4113-9749-2E7EE44C1EB1。
  13. 白领巧学燕子飞可治颈椎疼
  14. 常用的一些LDO芯片及使用
  15. 小记!华为 8.0系统切换APP内语言(中英文)无效(其他版本手机均有效)。
  16. 基于二叉排序树的高校分数查询系统
  17. Hadoop学习笔记(一)
  18. 2023最新智简魔方快云模板源码+已免授权
  19. xml 转换 --倾斜文本矩形框 (cx,cy,w,h,ang)到四个角坐标点(x1,y1,x2,y2,x3,y3,x4,y4)
  20. stm32—温湿度传感器

热门文章

  1. Oracle AWR ASH
  2. PGM学习之二 PGM模型的分类与简介
  3. VS里的新建模板(自动添加版本注释)
  4. 加快Vue项目的开发速度
  5. 英语 面包为什么不可数?
  6. [Ajax] jQuery中的Ajax -- 04-异步提交表单
  7. Vue.Draggable拖拽功能的配置和使用方法
  8. JavaScript算法(实例七)空瓶子换汽水问题
  9. Batch Normalization批量归一化
  10. 添加lua_C++/Lua高级交互