力扣-852. 山脉数组的峰顶索引

1. 题目

题目地址(852. 山脉数组的峰顶索引 - 力扣(LeetCode))

https://leetcode.cn/problems/peak-index-in-a-mountain-array/?envType=study-plan-v2&envId=primers-list

题目描述

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

  • arr.length >= 3
  • 存在 i0 < 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

你必须设计并实现时间复杂度为 O(log(n)) 的解决方案。

 

示例 1:

输入:arr = [0,1,0]
输出:1

示例 2:

输入:arr = [0,2,1,0]
输出:1

示例 3:

输入:arr = [0,10,5,2]
输出:1

 

提示:

  • 3 <= arr.length <= 105
  • 0 <= arr[i] <= 106
  • 题目数据保证 arr 是一个山脉数组

2. 题解

2.1 二分法

思路

由于题目要求时间复杂度为O(logn), 所以采用二分法
关于二分法详情参考:二分查找

代码

  • 语言支持:C++

C++ Code:


class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int n = arr.size();
        
        // 左闭右闭 [1, n - 2]
        // int left = 1, right = n - 2, ans = 0; // 因为是山脉数组, 必然两头 0和 n-1 是不可能的, 要找的话往中间找[1, n-2] / [1, n - 1)
        // while(left <= right){    
        //     int mid = (left + right) / 2;   
        //     if(arr[mid] > arr[mid+1]){
        //         right = mid - 1;
        //     } else{
        //         left = mid + 1;
        //     }
        // }

        
        // 左闭右开 [1, n - 1)
        // [left, right) -> [left, mid) / [mid+1, right) , 结束[left, left)
        // 这里即使[left, mid) 中的 mid是最后一个也没关系, 必然会走 left = mid新(=mid旧-1) + 1,
        int left = 1, right = n - 1, ans = 0;
        while(left < right){
            int mid = (left + right) / 2;   
            if(arr[mid] > arr[mid+1]){
                right = mid;
            } else{
                left = mid + 1;
            }
        }
        return left;

    }
};

复杂度分析

令 n 为数组长度。

  • 时间复杂度:\(O(logn)\)
  • 空间复杂度:\(O(1)\)
posted @ 2024-04-30 08:59  DawnTraveler  阅读(4)  评论(0编辑  收藏  举报