5227. K 次操作后最大化顶端元素(贪心)

243 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

每日刷题第62天 2021.03.12

5227. K 次操作后最大化顶端元素

题目

  • 给你一个下标从开始的整数数组 nums ,它表示一个 栈 ,其中 nums[0] 是栈顶的元素。
  • 每一次操作中,你可以执行以下操作 之一 :
  • 如果栈非空,那么 删除 栈顶端的元素。
  • 如果存在 1 个或者多个被删除的元素,你可以从它们中选择任何一个,添加 回栈顶,这个元素成为新的栈顶元素。
  • 同时给你一个整数 k ,它表示你总共需要执行操作的次数。
  • 请你返回恰好执行 次操作以后,栈顶元素的 最大值 。如果执行完 次操作以后,栈一定为空,请你返回 -1 。

示例

  • 示例1
输入:nums = [5,2,2,4,0,6], k = 4
输出:5
解释:
4 次操作后,栈顶元素为 5 的方法之一为:
- 第 1 次操作:删除栈顶元素 5 ,栈变为 [2,2,4,0,6] 。
- 第 2 次操作:删除栈顶元素 2 ,栈变为 [2,4,0,6] 。
- 第 3 次操作:删除栈顶元素 2 ,栈变为 [4,0,6] 。
- 第 4 次操作:将 5 添加回栈顶,栈变为 [5,4,0,6] 。
注意,这不是最后栈顶元素为 5 的唯一方式。但可以证明,4 次操作以后 5 是能得到的最大栈顶元素。
  • 示例2
输入:nums = [2], k = 1
输出:-1
解释:
第 1 次操作中,我们唯一的选择是将栈顶元素弹出栈。
由于 1 次操作后无法得到一个非空的栈,所以我们返回 -1 。

思路分析

  • nums的长度为n,根据题意:
    • 如果栈中只有一个元素(n == 1),k为奇数次,只能将其拿走,不能放回来,此时栈空,返回-1;K为偶数时,可重复进行拿走,换回来(这两个操作),最终返回nums[0]
  • 除预处理之外的其他情况:
    • 注意:栈中的下标是从0开始的,执行k次操作,最多取到0 ~ k -1为下标的元素,完成k次操作;或者取走0 ~ K - 2为下标的元素(执行k - 1次操作),放回去一个元素,完成k次操作。
    • k < n有两种情况:1.取k - 1次,放回去一个 (等价于)=> 求前k - 1个元素的最大值;2.取k 次,不放回去 (等价于)=> 当前栈顶的元素就是最大值;因此需要将两种情况的最大值,取max
    • k == n只有一种情况:若取k个元素,那么最终栈中就会为空,不符合题意;因此只能取k - 1个元素,最后将这k - 1个元素的最大值放入到栈顶
    • k > n只有一种情况:
      • k == n + 1,既然k是大于n的,除了取数组中n个元素,再使用最后一步将最大值放回栈顶。
      • K > n + 1,取栈中所有元素的最大值返回

AC代码

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var maximumTop = function(nums, k) {
  let n = nums.length;
  if(n == 1){
    if(k % 2 == 0){
      return nums[0];
    }else {
      return -1;
    }
  }else if(k < n) {
    let max = nums[k];
    for(let i = 0; i <= k - 2; i++) {
      if(max <= nums[i]){
        max = nums[i];
      }
    }
    return max;
  }else if(k == n) {
    let max = 0;
    for(let i = 0; i < k - 1; i++) {
      if(max <= nums[i]){
        max = nums[i];
      }
    }
    return max;
  }else if(k > n) {
    let max = 0;
    for(let i = 0; i < n; i++) {
      if(max <= nums[i]){
        max = nums[i];
      }
    }
    return max;
  }
};

总结

  • 贪心的思路:比较简单,但是思维上还是需要多加锻炼
  • 做题的速度有待提高。