1. 程式人生 > >leetcode-162-尋找峰值(find peak element)-java

leetcode-162-尋找峰值(find peak element)-java

題目及測試

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;
    }
}