leetcode-162-尋找峰值(find peak element)-java
阿新 • • 發佈:2018-12-29
題目及測試
package pid162; /*尋找峰值 峰值元素是指其值大於左右相鄰值的元素。 給定一個輸入陣列 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素並返回其索引。 陣列可能包含多個峰值,在這種情況下,返回任何一個峰值所在位置即可。 你可以假設 nums[-1] = nums[n] = -∞。 示例 1: 輸入: nums = [1,2,3,1] 輸出: 2 解釋: 3 是峰值元素,你的函式應該返回其索引 2。 示例 2: 輸入: nums = [1,2,1,3,5,6,4] 輸出: 1 或 5 解釋: 你的函式可以返回索引 1,其峰值元素為 2; 或者返回索引 5, 其峰值元素為 6。 說明: 你的解法應該是 O(logN) 時間複雜度的。 */ public class main { public static void main(String[] args) { int[][] testTable = {{1,2,3,1},{1,2,1,3,5,6,4},{1,2},{3,2,1,5,6,4}}; for (int[] ito : testTable) { test(ito); } } private static void test(int[] ito) { Solution solution = new Solution(); int rtn; long begin = System.currentTimeMillis(); for (int i = 0; i < ito.length; i++) { System.out.print(ito[i]+" "); } System.out.println(); //開始時列印陣列 rtn = solution.findPeakElement(ito);//執行程式 long end = System.currentTimeMillis(); //System.out.println(ito + ": rtn=" + rtn); System.out.println(": rtn=" +rtn); System.out.println(); System.out.println("耗時:" + (end - begin) + "ms"); System.out.println("-------------------"); } }
解法1(成功,3ms,極快)
直接順序查詢,看now>prev&&now>next即可
package pid162; import java.util.Arrays; import javax.naming.InitialContext; public class Solution { public int findPeakElement(int[] nums) { int length=nums.length; if(length==1){ return 0; } int prev=nums[0]; int now=nums[1]; int next; int index=0; for(int i=1;i<length-1;i++){ next=nums[i+1]; if(now>prev&&now>next){ index=i; break; } prev=now; now=next; } if(nums[0]>nums[1]){ index=0; } if(nums[length-1]>nums[length-2]){ index=length-1; } return index; } }
解法2(別人的)
陣列中必有一個峰,因為最左端和最右端元素只要比旁邊的大,也可以當峰
題目中已經說明,最左端和最右端元素均無限小,中間元素比兩側都要大,那麼本題中一定存在一個峰元素。所以不管中間有多少波峰,只要找到峰元素,我們只需找到剛剛開始下降而未下降的位置。採用二分查詢,查出這樣一個位置即可,我們知道二分查詢要比較的是 target 元素,本題的 target 元素是 mid 的後一個元素,即 nums[mid] 與 nums[mid+1] 進行比較:
public class Solution { public int findPeakElement(int[] nums) { int left = 0, right = nums.length - 1; while (left < right) { int mid = (left + right) / 2; if(nums[mid] < nums[mid + 1]) left = mid + 1; else right = mid; } return left; } }