LeetCode:Find Peak Element - 尋找一個數組內的頂點

一、題目名稱java

Find Peak Element(尋找一個數組內的頂點)數組

二、題目地址code

https://leetcode.com/problems/find-peak-element/遞歸

三、題目內容索引

英文:ip

A peak element is an element that is greater than its neighbors.element

Given an input array where num[i] ≠ num[i+1], find a peak element and return its index.leetcode

The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.開發

You may imagine that num[-1] = num[n] = -∞.get

中文:

在一個數組內,若是某元素比它左右兩個元素都大,則稱該元素爲一個「頂點」。現給出一個相鄰元素必定不相同的數組,找出一個頂點元素並返回它的索引。一個數組中可能包含多個頂點,在這種狀況下返回任意一個頂點的座標便可。你能夠假定第-1個元素和第n個元素是負無窮(這句話的意思就是最左邊的元素假定它「再左邊」還有一個比它小的元素,最右邊的元素同理)。

例如:給定數組 [1, 2, 3, 1],則元素3是一個頂點,應返回它的索引值2

四、解題方法1

最容易想到的辦法天然是自左至右遍歷數組,若是某元素比它左邊和右邊的元素大,則該元素必爲頂點。返回找到的第一個頂點便可。

Java代碼以下:

/**
 * @功能說明:LeetCode 162 - Find Peak Element
 * @開發人員:Tsybius2014
 * @開發時間:2015年11月4日
 */
public class Solution {
    
    /**
     * 尋找頂點
     * @param nums
     * @return
     */
    public int findPeakElement(int[] nums) {
        
        if (nums == null) {
            return -1;
        } else if (nums.length == 0) {
            return -1;
        } else if (nums.length == 1) {
            return 0;
        } else if (nums[0] > nums[1]) {
            return 0;
        } else if (nums[nums.length - 1] > nums[nums.length - 2]) {
            return nums.length - 1;
        }
        
        for (int i = 1; i < nums.length - 1; i++) {
            if (nums[i - 1] <= nums[i] && nums[i + 1] <= nums[i]) {
                return i;
            }
        }
        
        return -1;
    }
}

四、解題方法2

另外一種方法是使用二分查找法解決問題。這個方法利用了題目中的以下性質:

1)最左邊的元素,它「更左邊」的元素比它小(負無窮),咱們認爲它是一個增加的方向

2)最右邊的元素,它「更右邊」的元素比它小(也是負無窮),咱們認爲它是一個降低的方向

根據這兩點咱們能夠判斷:最左邊和最右邊的元素圍成的區域內,必有至少一個頂點

如今咱們找到中點 nums[mid],將它與 nums[mid + 1] 做比較,若是前者較小,則方向是增加,與最左邊的元素是一致的,就把左邊界挪到mid+1的位置;不然與最右邊的元素一致,將右邊界挪到mid的位置。

這個方法的原理就是當左邊界方向爲「增加」,右邊界方向爲「降低」時,兩者圍出的區域必有一個頂點。咱們能夠寫出以下Java代碼實現此方法:

/**
 * @功能說明:LeetCode 162 - Find Peak Element
 * @開發人員:Tsybius2014
 * @開發時間:2015年11月4日
 */
public class Solution {
    
    /**
     * 尋找頂點
     * @param nums
     * @return
     */
    public int findPeakElement(int[] nums) {
        
        if (nums == null) {
            return -1;
        } else if (nums.length == 0) {
            return -1;
        } else if (nums.length == 1) {
            return 0;
        } 

        int left = 0;
        int mid = 0;
        int right = nums.length - 1;
        
        while (left < right) {
            mid = left + (right - left) / 2;
            if (nums[mid] < nums[mid + 1]) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        
        return left;
    }
}

本題也可使用遞歸的方式進行二分搜索。

END

相關文章
相關標籤/搜索