1. 题目
符合下列属性的数组 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.1 示例
- 示例 1 1 1:
- 输入:
arr = [0, 1, 0]
- 输出: 1 1 1
- 示例 2 2 2:
- 输入:
arr = [0, 2, 1, 0]
- 输出: 1 1 1
- 示例 3 3 3:
- 输入:
arr = [0, 10, 5, 2]
- 输出: 1 1 1
- 示例 4 4 4:
- 输入:
arr = [3, 4, 5, 1]
- 输出: 2 2 2
- 示例 5 5 5:
- 输入:
arr = [24, 69, 100, 99, 79, 78, 67, 36, 26, 19]
- 输出: 2 2 2
1.2 说明
- 来源: 力扣(LeetCode)
- 链接: https://leetcode-cn.com/problems/peak-index-in-a-mountain-array
1.3 提示
- 3 ≤ a r r . l e n g t h ≤ 1 0 4 3 \le arr.length \le 10^4 3≤arr.length≤104
- 0 ≤ a r r [ i ] ≤ 1 0 6 0 \le arr[i] \le 10^6 0≤arr[i]≤106
- 题目数据保证
arr
是一个山脉数组
1.4 进阶
很容易想到时间复杂度 O ( n ) O(n) O(n) 的解决方案,你可以设计一个 O ( l o g ( n ) ) O(log(n)) O(log(n)) 的解决方案吗?
2. 解法一
2.1 分析
略。
2.2 解答
from typing import List
class Solution:
def peak_index_in_mountain_array(self, arr: List[int]) -> int:
left, right = 0, len(arr) - 1
while left <= right - 2:
mid = left + (right - left) // 2
if arr[mid - 1] < arr[mid] > arr[mid + 1]:
return mid
elif arr[mid] > arr[mid + 1]:
right = mid
elif arr[mid] > arr[mid - 1]:
left = mid
def main():
arr = [24, 69, 100, 99, 79, 78, 67, 36, 26, 19]
# arr = [3, 4, 5, 1]
sln = Solution()
print(sln.peak_index_in_mountain_array(arr)) # 2
if __name__ == '__main__':
main()
- 执行用时: 36 ms , 在所有 Python3 提交中击败了 85.40% 的用户;
- 内存消耗: 15.8 MB , 在所有 Python3 提交中击败了 53.48% 的用户。
- 时间复杂度: O ( l o g n ) O(logn) O(logn),其中 n n n 是数组
arr
的长度。我们需要进行二分查找的次数为 O ( l o g n ) O(logn) O(logn) ;- 空间复杂度: O ( 1 ) O(1) O(1)。
更加优雅的解法如下:
from typing import List
class Solution:
def elegant_peak_index(self, arr: List[int]) -> int:
left, right, idx = 1, len(arr) - 2, 0
while left <= right:
mid = (left + right) // 2
if arr[mid] > arr[mid + 1]:
idx = mid
right = mid - 1
else:
left = mid + 1
return idx
def main():
arr = [24, 69, 100, 99, 79, 78, 67, 36, 26, 19]
# arr = [3, 4, 5, 1]
sln = Solution()
print(sln.elegant_peak_index(arr)) # 2
if __name__ == '__main__':
main()