Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
每日刷题第62天 2021.03.12
5227. K 次操作后最大化顶端元素
- leetcode原题链接:leetcode-cn.com/problems/ma…
- 难度:中等
- 方法:贪心
题目
- 给你一个下标从
0开始的整数数组nums,它表示一个 栈 ,其中nums[0]是栈顶的元素。 - 每一次操作中,你可以执行以下操作 之一 :
- 如果栈非空,那么 删除 栈顶端的元素。
- 如果存在
1个或者多个被删除的元素,你可以从它们中选择任何一个,添加 回栈顶,这个元素成为新的栈顶元素。 - 同时给你一个整数
k,它表示你总共需要执行操作的次数。 - 请你返回恰好执行
k次操作以后,栈顶元素的 最大值 。如果执行完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次,不放回去 (等价于)=> 当前栈顶的元素就是最大值;因此需要将两种情况的最大值,取maxk == 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;
}
};
总结
- 贪心的思路:比较简单,但是思维上还是需要多加锻炼
- 做题的速度有待提高。