【每日一题】【12.18】162.寻找峰值

 博客主页: A_SHOWY
系列专栏:力扣刷题总结录 数据结构  云计算  数字图像处理  力扣每日一题_

1.题目链接

162. 寻找峰值icon-default.png?t=N7T8https://leetcode.cn/problems/find-peak-element/

2.题目详情 

【每日一题】【12.18】162.寻找峰值_第1张图片

今天是一道mid题目,关于寻找峰值,它要求时间复杂度为logn,就能大概猜出来这道题目要用二分法,但是如果这道题目用o(n)的方法做也能通过,而且非常简单。 

3.题目分析解答 

方法一:直接找vector容器中的最大值

class Solution {
public:
    int findPeakElement(vector& nums) {
      return max_element(nums.begin(),nums.end()) - nums.begin();
    }
};

 官方题解中用到的*min_element函数,发现这个函数很方便的用于求vector容器中的最小元素。

int maxPosition = max_element(n.begin(),n.end()) - n.begin(); //最大值下标

int minPosition = min_element(n.begin(),n.end()) - n.begin();//最小值下标

方法二:迭代爬坡 

class Solution {
public:
      
    int findPeakElement(vector& nums) {
        int n = nums.size();
        int idx = rand() % n;//找一个0到n-1的随机数
//处理边界情况
      auto get = [&](int i) -> pair{
          if(i == -1 || i == n) return {0,0};
          return {1,nums[i]};
      };

        while(!(get(idx - 1) < get(idx) && get(idx) > get(idx + 1)))
        {
            if(get(idx -1) > get(idx)) idx  -= 1;
            else idx += 1;
        }
return idx;
    }
};

1.需要注意的是,先找一个随机数, 

int idx = rand() % n;//找一个0到n-1的随机数

2.注意处理边界情况用这个lambda函数,Lambda 表达式中的 [&] 表示捕获外部所有变量,int i表示接收一个整型参数

3.pair 表示了两个 int 类型的值,确实是一个键值对结构。但在这里,Lambda 函数返回的不是键值对,而是一个表示有效性和数组值的两个值的 pair。在 get Lambda 函数中,使用了 pair 结构来表示两个含义不同的整数。其中,第一个整数表示索引是否有效(0 表示无效,1 表示有效),第二个整数表示索引位置上的数组值。这个结构在代码中的意图是标记数组索引的有效性,并提供索引位置上的值。

 4.核心思路:

如果nums[i- 1] nums[i+1],那么位置à就是峰值位置,我们可以直接返回i作为答案;
如果nums[i-1]< nums[i] < nums[i+1],那么位置i处于上坡,我们需要往右走
如果nums[i-1] >nums[i]>nums[i+1],那么位置i处于下坡,我们需要往左走
如果nums[i-1] >nums[i]  

方法三:改进的二分法

class Solution {
public:
      
    int findPeakElement(vector& nums) {
        int n = nums.size();
//处理边界情况
      auto get = [&](int i) -> pair{
          if(i == -1 || i == n) return {0,0};
          return {1,nums[i]};
      };
     int left = 0,right = n - 1,ans = -1;
     while(left <= right)
     {
         int mid = (right + left)/2;
         if(get(mid -1) < get(mid) && get(mid) > get(mid+1))
         {
             ans = mid;
             break;
         }
         else if(get(mid) < get(mid + 1)) left = mid+1;
         else right = mid -1;
     }
    return ans;
    }
};

核心思路:对于当前可行的下标范围[l, r],我们随机一个下标i;
如果下标i是峰值,我们返回i作为答案;
如果nums[i]< numsi+1],那么我们抛弃1,i的范围,在剩余[i+1,r]的范围内继续随机选取下标。
如果nums[i]> nums[i+1],那么我们抛弃[i,r]的范围,在剩余[l,i-1]的范围内继续随机选取下标。

其他的思路和方法二其实是一样的

4.打卡

【每日一题】【12.18】162.寻找峰值_第2张图片

你可能感兴趣的:(力扣每日一题,算法,数据结构,c++,leetcode)