力扣852(java&python)-山脉数组的峰顶索引(中等)
题目:
符合下列属性的数组 arr 称为 山脉数组 :
- arr.length >= 3
- 存在 i(0 < i < arr.length - 1)使得:
- arr[0] < arr[1] < ... arr[i-1] < arr[i]
- arr[i] > arr[i+1] > ... > arr[arr.length - 1]
- 给你由整数组成的山脉数组 arr ,返回任何满足 arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1] 的下标 i 。
示例 1:
输入:arr = [0,1,0]
输出:1
示例 2:
输入:arr = [0,2,1,0]
输出:1
示例 3:
输入:arr = [0,10,5,2]
输出:1
示例 4:
输入:arr = [3,4,5,1]
输出:2
示例 5:
输入:arr = [24,69,100,99,79,78,67,36,26,19]
输出:2
提示:
- 3 <= arr.length <= 104
- 0 <= arr[i] <= 106
- 题目数据保证 arr 是一个山脉数组
进阶:很容易想到时间复杂度 O(n) 的解决方案,你可以设计一个 O(log(n)) 的解决方案吗?
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/peak-index-in-a-mountain-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
【二分查找】
其实看到提示中进阶要求设计时间复杂度为O(log(n))的时候就会想到二分查找,加上题目中给定的数组可以看做两个有序的数组,先升序(上山)后降序(下山),目的就是找到升序中最后的那一个数字(山顶)的下标。用二分查找:
- 初始化左右边界:left = 0, right = n - 1,计算出mid
- 循环条件是:left < right,判断的条件就让mid与 mid - 1的数值进行判断
- arr[mid] > = arr[mid - 1]:说明mid还处于上山阶段,此时mid有可能就是山顶,需要往右继续找山顶,搜索区间变为[mid, right],即让left = mid(注意:mid需要向上取整);
- arr[mid] < arr[mid-1]:说明mid已经处于下山阶段,就需要往左寻找山顶,搜索区间变为[left, mid - 1],即让right = mid - 1;
- 循环结束的条件是:left == right,题目中说了 arr 是一个山脉数组,那么最后一定会是山顶,直接返回 left 或者 right 即可。
java代码(left < right):
1 class Solution {
2 public int peakIndexInMountainArray(int[] arr) {
3 int n = arr.length;
4 int left = 0, right = n - 1;
5 while (left < right){
6 int mid = left + (right - left + 1) / 2;
7 if (arr[mid] > arr[mid -1]){
8 left = mid;
9 }else{
10 right = mid - 1;
11 }
12 }
13 return left;
14 }
15 }

python3代码(left <= right):错误代码:
1 class Solution:
2 def peakIndexInMountainArray(self, arr: List[int]) -> int:
3 left, right = 0, len(arr) - 1
4 while left <= right:
5 mid = left + (right - left) // 2
6 if arr[mid] > arr[mid - 1] and arr[mid] > arr[mid + 1]:
7 return mid
8 # arr[mid] > arr[mid - 1]并且arr[mid] <= arr[mid + 1]
9 # mid + 1更大
10 elif arr[mid] > arr[mid - 1]:
11 left = mid + 1
12 else:
13 # arr[mid] > arr[mid + 1]并且arr[mid]<= arr[mid -1]
14 # mid - 1更大
15 right = mid - 1
16 return -1
有一个测试用例过不去:

研究一下它为什么过不去:
[3,9,8,6,4]
①left = 0, right = 4, mid = 2, arr[2] > arr[3]且arr[2] < arr[1]故right = mid -1 = 1;
②left = 0, right = 1,mid = 0, 这时mid -1 = -1已经数组越界了,故为了避免这种判断,arr[mid+1] > arr[mid] 必须写在 arr[mid-1]>arr[mid] 前面判断。跟着正确的,arr[1] > arr[0],left = mid + 1 = 1;
③left = 1,right = 1,mid = 1,arr[0] < arr[1] < arr[2],故直接返回mid = 1。
python3正确代码:
1 class Solution:
2 def peakIndexInMountainArray(self, arr: List[int]) -> int:
3 left, right = 0, len(arr) - 1
4 while left <= right:
5 mid = left + (right - left) // 2
6 if arr[mid] > arr[mid + 1] and arr[mid] > arr[mid - 1]:
7 return mid
8 # arr[mid] > arr[mid + 1]并且arr[mid]<= arr[mid -1]
9 # mid - 1更大
10 elif arr[mid] > arr[mid + 1]:
11 right = mid - 1
12 else:
13 # arr[mid] > arr[mid - 1]并且arr[mid] <= arr[mid + 1]
14 # mid + 1更大
15 left = mid + 1
16 return -1

力扣852(java&python)-山脉数组的峰顶索引(中等)的更多相关文章
- Leetcode之二分法专题-852. 山脉数组的峰顶索引(Peak Index in a Mountain Array)
Leetcode之二分法专题-852. 山脉数组的峰顶索引(Peak Index in a Mountain Array) 我们把符合下列属性的数组 A 称作山脉: A.length >= 3 ...
- 力扣(LeetCode) 852. 山脉数组的峰顶索引
我们把符合下列属性的数组 A 称作山脉: A.length >= 3 存在 0 < i < A.length - 1 使得A[0] < A[1] < ... A[i-1] ...
- LeetCode 852. Peak Index in a Mountain Array (山脉数组的峰顶索引)
题目标签:Binary Search 题目给了我们一组 int array,让我们找到数组的 peak. 利用 binary search, 如果数字比它后面那个数字小,说明还在上坡,缩小范围到右半边 ...
- LeetCode 852. 山脉数组的峰顶索引 (二分)
题目链接:https://leetcode-cn.com/problems/peak-index-in-a-mountain-array/ 我们把符合下列属性的数组 A 称作山脉: A.length ...
- 力扣(LeetCode)寻找数组的中心索引 个人题解
给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法. 我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和. 如果数组不存在中心索引,那么我 ...
- [Swift]LeetCode852. 山脉数组的峰顶索引 | Peak Index in a Mountain Array
Let's call an array A a mountain if the following properties hold: A.length >= 3 There exists som ...
- 力扣 -- 寻找两个有序数组的中位数 Median of Two Sorted Arrays python实现
题目描述: 中文: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums ...
- 力扣1052. 爱生气的书店老板-C语言实现-中等难度
题目 传送门 文本 今天,书店老板有一家店打算试营业 customers.length 分钟.每分钟都有一些顾客(customers[i])会进入书店,所有这些顾客都会在那一分钟结束后离开. 在某些时 ...
- 力扣(LeetCode)561. 数组拆分 I
给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大. 示例 ...
- 力扣Leetcode 面试题51. 数组中的逆序对 - 归并排序
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: 0 <= ...
随机推荐
- navigator.aardio 代码备份
import win.ui; import console; import process; import string.regex; import libs.router; /*DSG{{*/ ma ...
- 音频wav文件转sbc工具wav2sbc下载
前记: 书到用时方恨少,工具用时方才发现好不到.为了一个工具,也是折腾了有一阵了. 工具说明: 在耳机中,各大芯片公司为了节省内存,本地播放的一般都是sbc格式文件,这就用到了wav转sbc文件的软件 ...
- 安装swagger过程及遇到问题
参考:欢迎点击原文:https://www.cnblogs.com/liconglong/p/11477401.html(主要) https://blog.csdn.net/liangjiabao55 ...
- dbvisualizer之编辑区中文乱码问题
!在SQL Commander中,sql语句中如果有中文,显示是'口口口'. 解决办法如下: 在Tools->tool Properties->General->Appearance ...
- Java双重循环实现任意字符串中提取数字子串
public class Test2{ public static void main(String[] args) { String s = "211ahn678rh2kkk0731 ...
- epoll水平触发与边缘触发
把高电平看作文件描述符是可读或可写状态,低电平黑色表示不可读或不可写,epoll_wait的水平触发就是蓝色的时候epoll_wait就会被触发,而边缘触发就是红色的时候epoll_wait会触发,且 ...
- MySQL数据库InnnoDB引擎事务说明
前言 本篇文章主要讲诉数据库中事务的四大特性(ACID)以及事务的隔离级别划分. 数据库事务及其特性 事务是指满足ACID特性的一组操作,可以通过 Commit 提交一个事务,也可以使用 Roll ...
- 常用命令rsyncscp-1
常用命令:rsync/scp scp scp命令文件传输 scp命令用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能 ...
- 记录--Vue3问题:如何实现组件拖拽实时预览功能?
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 1. 需求分析 实现一个CMS内容管理系统,在后台进行内容编辑,在官网更新展示内容. 关于后台的编辑功能,大致分为两部分:组件拖拽预览.组 ...
- JAVA10进制数转45进制
import java.util.HashMap; public class test2 { // 定义45进制数字 private static final String X45 = "0 ...