162. Find Peak Element

来源:互联网 发布:乐语软件下载 编辑:程序博客网 时间:2024/05/16 19:14

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

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

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] = -∞.

For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2.

这道题最初的想法就是遍历一遍数组,找到符合题目要求的就输出,只是需要对首元素与尾元素多加一个判断 ,时间复杂度为O(n)

 public int findPeakElement(int[] nums) {
     // 特殊情况处理
     if(nums == null || nums.length == 0){
         return -1;
     }else if(nums.length == 1){
         return 0;
     }
     
     for(int i = 0; i < nums.length; i++){
         if(i == 0){
             if(nums[i] > nums[i + 1]){
                 return i;
             }
         }else if(i == nums.length - 1){
             if(nums[i - 1] < nums[i]){
                 return i;
             }
         }else{
             if(nums[i] > nums[i - 1] && nums[i] > nums[i + 1]){
                 return i;
             }
         }
     }
     
     return 0;
    }

另外一种想法是参考了别人的,这种做法可以减少比较的次数,上一个解决方法的比较次数是2*n,而这种解决方案的比较次数为n,代码如下:

public int findPeakElement(int[] nums) {
     // 特殊情况处理
     if(nums == null || nums.length == 0){
         return -1;
     }else if(nums.length == 1){
         return 0;
     }
     
     for(int i = 1; i < nums.length; i++){
         if(nums[i] < nums[i - 1]){
             return i - 1;
         }
     }
     
     return nums.length - 1;
    }

但是题目要求我们为log的算法复杂度,由于题目说明可能有多个峰值点,这把我迷惑了,我想这怎么可能二分查找呢,但最终我们只要返回一个峰值元素就好,因此还是可以利用二分查找,代码如下:

public int findPeakElement(int[] nums) {
     // 特殊情况处理
     if(nums == null || nums.length == 0){
         return -1;
     }else if(nums.length == 1){
         return 0;
     }
     
     int left = 0, right = nums.length - 1;
     while(left <= right){
         int mid = (left + right) / 2;
         // 通过对比相邻元素减少区间
         if(left == right){
            return left;
         }else if(nums[mid] < nums[mid + 1]){
             left = mid + 1;
         }else{
             right = mid;
         }
     }
     return left;
    }

这样将算法的时间复杂度降低至logn,该题分析结束。

0 0