查看原文
其他

571,山脉数组的峰顶索引

博哥 数据结构和算法 2022-05-19

This is the best summer I've ever had.

这是我度过最好的一个夏天。

问题描述



来源:LeetCode第852题

难度:简单


符合下列属性的数组arr称为山脉数组

1,arr.length>=3

2,存在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 <= 10^4

  • 0 <= arr[i] <= 10^6

  • 题目数据保证arr是一个山脉数组


直接查找



之前讲过475,有效的山脉数组,而这题是让找出山脉数组的峰顶索引,我们看提示的最后一条是题目数据保证arr是一个山脉数组,也就是山脉数组一定是存在的,所以不需要判断,直接查找即可。

山脉数组是先上升然后在下降,如果当前元素比右边挨着的小,说明开始下降了,那么当前元素就是山脉数组的峰顶,只需要返回他的索引即可

1public int peakIndexInMountainArray(int[] arr) {
2    for (int i = 0; i < arr.length - 1; ++i)
3        if (arr[i] > arr[i + 1])
4            return i;
5    return 0;
6}


二分法解决



山脉数组前面部分是升序的,后面部分是降序的,所以也可以使用二分法,用中间的值和他的下一个比较(根据题中对山脉数组的定义,以及提示的最后一条,所以数组中挨着的两个数字不可能相同,要么比下一个小,要么比下一个大)

  • 如果比下一个小,说明还处在上升阶段,缩小查找的范围到[mid+1,right]

  • 如果比下一个大,说明处在下降阶段,缩小查找范围到[left,mid]

1public int peakIndexInMountainArray(int[] arr) {
2    int left = 0;
3    int right = arr.length - 1;
4    while (left < right) {
5        int mid = left + (right - left) / 2;
6        //如果mid比他后面的小,说明是在上升,缩小范围
7        if (arr[mid] < arr[mid + 1])
8            left = mid + 1;
9        else
10            right = mid;
11    }
12    return left;
13}

或者还可以写成递归的形式

1public int peakIndexInMountainArray(int[] arr) {
2    return helper(arr, 0, arr.length - 1);
3}
4
5public int helper(int[] arr, int left, int right) {
6    int mid = left + (right - left) / 2;
7    //比左右两个都大,说明是峰顶,直接返回
8    if (arr[mid] > arr[mid - 1] && arr[mid] > arr[mid + 1])
9        return mid;
10    //mid指向的值处在爬升阶段
11    if (arr[mid] < arr[mid + 1])
12        return helper(arr, mid + 1, right);
13    return helper(arr, left, mid);
14}


562,数组中的最长山脉

539,双指针解删除有序数组中的重复项

527,两个数组的交集 II

516,贪心算法解按要求补齐数组


截止到目前我已经写了500多道算法题了,为了方便大家阅读,我把部分算法题整理成了pdf文档,目前有1000多页,大家可以在公众号中回复关键字“pdf”即可获取下载链接。


你点的每个赞,我都认真当成了喜欢

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存