leetcode 162. Find Peak Element | 162. 寻找峰值(二分法找局部最大值)
題目
https://leetcode.com/problems/find-peak-element/
題解
2021-7-21 16:28:31 更新版思路:
根據左神在 課上 說的,可以使用二分法找到局部最小值,看上升或下降坡度,則有點類似于羅爾定理的感覺。同理,也可以用二分找到局部最大值,具體可以參考本題 英文版官方題解 或 中文版圖解.
羅爾定理:如果 R 上的函數 f(x) 滿足以下條件:
(1)在閉區間 [a,b] 上連續
(2)在開區間 (a,b) 內可導
(3)f(a)=f(b)
則至少存在一個 ξ∈(a,b),使得 f’(ξ)=0。
實際上,當我們找到一個上升沿的時候,可以推斷它的右邊必然有一個山峰,如果沒有的話,它就是最后一個上升沿,而最后一個上升沿的右端點,或者第一個下降沿的左端點也是山峰。
不嚴謹的證明過程,不保證正確…可以參考一下:
寫題時的原思路
看題目要求是 O(log n),想到每次刪一半,但是寫完之后才發現并不符合要求。。先將錯就錯吧,后面有空再完善下。
第一次比較次數為 n/2,第二次比較次數為 n/4,第三次8/n,…,總比較次數為 n/2+n/4+n/8+n/16+…= ?
根據《算法導論》“同時找最大最小元素的最小比較次數”的原理,也是每次刪一半,即不重復的兩兩比較。
所以每次淘汰一半后,最后剩下的是最大值,也就是 Peak Element。
class Solution {public int findPeakElement(int[] nums) {ArrayList<Integer> list = new ArrayList<>();ArrayList<Integer> index = new ArrayList<>();for (int i = 0; i < nums.length; i++) {list.add(nums[i]);index.add(i);}while (list.size() != 1) {ArrayList<Integer> newList = new ArrayList<>();ArrayList<Integer> newIndex = new ArrayList<>();for (int i = 0; i < list.size() - 1; i += 2) { // 兩兩比較,每次扔掉一半if (list.get(i) > list.get(i + 1)) {newList.add(list.get(i));newIndex.add(index.get(i));} else {newList.add(list.get(i + 1));newIndex.add(index.get(i + 1));}}if (list.size() % 2 == 1) { // 奇數個數情況,簡單起見,末尾元素無條件進入下一輪判斷newList.add(list.get(list.size() - 1));newIndex.add(index.get(index.size() - 1));}list = newList;index = newIndex;}return index.get(0);} } 超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的leetcode 162. Find Peak Element | 162. 寻找峰值(二分法找局部最大值)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode 328. Odd Ev
- 下一篇: leetcode 331. Verify