LeetCode——162. Find Peak Element

一.題目連接:算法

  https://leetcode.com/problems/find-peak-element/數組

二.題目大意:spa

  給定一個長度爲N的一維數組,數組是無序的,要求找到數組中的極大值(或局部最大值),並返回該極大值的下標,並假設 nums[-1] = nums[n] = -∞.;當某元素同時大於它兩邊的元素時,則該元素是數組中的一個極大值,數組中若存在多個極大值,則返回任意一個便可。.net

算法的時間複雜度要求爲log級別。code

三.題解:blog

  這個問題的最直觀的解法,就是遍歷一遍數組,而後判斷每一個元素是否符合極大值的條件,可是時間複雜度爲O(N),不符合題目的要求。既然要求是對數級別的時間複雜度,那就不妨利用二分法的思想來查找符合條件的元素。element

代碼以下:leetcode

class Solution
{
public:
    int findPeakElement(vector<int>& nums)
    {
        if(nums.empty())
            return -1;
        int len = nums.size();
        int low = 0;
        int high = len - 1;
        while(low < high - 1)//至少要省出一箇中間值來,因此low < high -1
        {
            int mid  = ((high - low) >> 1) + low;//一位運算符的優先級比較低,因此必定加上括號
            if(nums[mid] > nums[mid + 1] && nums[mid] > nums[mid - 1])
                return mid;
            else if(nums[mid] < nums[mid + 1])
            {
                if (low == mid)//特殊狀況,必須經過low = mid + 1跳出這種循環
                    low = mid + 1;
                else
                    low = mid;
            }

            else
                high = mid;
        }
        return nums[low] > nums[high] ? low : high;//有可能還沒找到mid就跳出循環了,此時low和high必有一個知足條件


    }
};

該算法的時間複雜度爲O(logN),空間複雜度爲O(1),可以知足題目的要求。有幾點須要注意:get

1.循環的終止條件爲low < high -1,由於極大值要同時大於兩邊的元素,因此至少要有三個值,不然就跳出循環。io

2.有種特殊狀況,就是low = mid後,再次更新mid的話,low與mid的值仍是相同,至關於陷入了死循環,此時經過low = mid + 1跳出死循環。

3.若是在循環中沒有返回mid的話,可能數組只有一個元素,也可能只有數組的末尾元素纔是極大值,因此最後要判斷一下low和high的值,並返回其中較大的。

四.題目擴展:

 若是數組爲二維數組的話,如何找到局部最大值(極大值)?

通常有三種方法:直接遍歷、利用二分法、利用畫圈法(分治)。具體能夠參考:https://www.jianshu.com/p/b4f5cb071f04  或者 https://blog.csdn.net/m0_37747541/article/details/79629457

相關文章
相關標籤/搜索