当我们遍历到下标 i 时,如果有 arr}{i-1} < \textit{arr}_i > \textit{arr}{i+1,那么 i 就是我们需要找出的下标。
更简单地,我们只需要让 i 满足 arr}i > \textit{arr}{i+1 即可。在遍历的过程中,我们最先遍历到的满足 arr}i > \textit{arr}{i+1 的下标 i 一定也满足 arr}_{i-1} < \textit{arr}_i。
代码
[sol1-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { public: intpeakIndexInMountainArray(vector<int>& arr){ int n = arr.size(); int ans = -1; for (int i = 1; i < n - 1; ++i) { if (arr[i] > arr[i + 1]) { ans = i; break; } } return ans; } };
[sol1-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution { publicintpeakIndexInMountainArray(int[] arr) { intn= arr.length; intans= -1; for (inti=1; i < n - 1; ++i) { if (arr[i] > arr[i + 1]) { ans = i; break; } } return ans; } }
[sol1-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13
publicclassSolution { publicintPeakIndexInMountainArray(int[] arr) { int n = arr.Length; int ans = -1; for (int i = 1; i < n - 1; ++i) { if (arr[i] > arr[i + 1]) { ans = i; break; } } return ans; } }
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11
classSolution: defpeakIndexInMountainArray(self, arr: List[int]) -> int: n = len(arr) ans = -1
for i inrange(1, n - 1): if arr[i] > arr[i + 1]: ans = i break return ans
[sol1-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12
var peakIndexInMountainArray = function(arr) { const n = arr.length; let ans = -1;
for (let i = 1; i < n - 1; ++i) { if (arr[i] > arr[i + 1]) { ans = i; break; } } return ans; };
[sol1-Golang]
1 2 3 4 5 6 7
funcpeakIndexInMountainArray(arr []int)int { for i := 1; ; i++ { if arr[i] > arr[i+1] { return i } } }
[sol1-C]
1 2 3 4 5 6 7 8 9 10 11
intpeakIndexInMountainArray(int* arr, int arrSize) { int n = arrSize; int ans = -1; for (int i = 1; i < n - 1; ++i) { if (arr[i] > arr[i + 1]) { ans = i; break; } } return ans; }
复杂度分析
时间复杂度:O(n),其中 n 是数组 arr 的长度。我们最多需要对数组 arr 进行一次遍历。
空间复杂度:O(1)。
方法二:二分查找
思路与算法
记满足题目要求的下标 i 为 i_\textit{ans。我们可以发现:
当 i < i_\textit{ans 时,arr}i < \textit{arr}{i+1 恒成立;
当 i \geq i_\textit{ans 时,arr}i > \textit{arr}{i+1 恒成立。
classSolution { public: intpeakIndexInMountainArray(vector<int>& arr){ int n = arr.size(); int left = 1, right = n - 2, ans = 0; while (left <= right) { int mid = (left + right) / 2; if (arr[mid] > arr[mid + 1]) { ans = mid; right = mid - 1; } else { left = mid + 1; } } return ans; } };
[sol2-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution { publicintpeakIndexInMountainArray(int[] arr) { intn= arr.length; intleft=1, right = n - 2, ans = 0; while (left <= right) { intmid= (left + right) / 2; if (arr[mid] > arr[mid + 1]) { ans = mid; right = mid - 1; } else { left = mid + 1; } } return ans; } }
[sol2-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
publicclassSolution { publicintPeakIndexInMountainArray(int[] arr) { int n = arr.Length; int left = 1, right = n - 2, ans = 0; while (left <= right) { int mid = (left + right) / 2; if (arr[mid] > arr[mid + 1]) { ans = mid; right = mid - 1; } else { left = mid + 1; } } return ans; } }
[sol2-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defpeakIndexInMountainArray(self, arr: List[int]) -> int: n = len(arr) left, right, ans = 1, n - 2, 0
while left <= right: mid = (left + right) // 2 if arr[mid] > arr[mid + 1]: ans = mid right = mid - 1 else: left = mid + 1 return ans
[sol2-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
var peakIndexInMountainArray = function(arr) { const n = arr.length; let left = 1, right = n - 2, ans = 0;
while (left <= right) { const mid = Math.floor((left + right) /2 ); if (arr[mid] > arr[mid + 1]) { ans = mid; right = mid - 1; } else { left = mid + 1; } } return ans; };
intpeakIndexInMountainArray(int* arr, int arrSize) { int n = arrSize; int left = 1, right = n - 2, ans = 0; while (left <= right) { int mid = (left + right) / 2; if (arr[mid] > arr[mid + 1]) { ans = mid; right = mid - 1; } else { left = mid + 1; } } return ans; }
复杂度分析
时间复杂度:O(\log n),其中 n 是数组 arr 的长度。我们需要进行二分查找的次数为 O(\log n)。