周赛284——[5227. K 次操作后最大化顶端元素]

236 阅读1分钟

原题:5227. K 次操作后最大化顶端元素 - 力扣(LeetCode) (leetcode-cn.com)

再次读秒绝杀第三题,玩的就是心理素质。。。

image-20220313172005795.png

前两题直接模拟就可以了,完成的比较快

第三题题目一开始翻译错误,估计不少人在这里比我WA了还多。。。

image-20220313162828673.png

读完题目看k的范围,十分的大,显然不能通过模拟每一步来做,不然必定超时。一般这种就只能反过来,不要模拟,而是去想,对于数组中的某个数,我怎么才能取到它作为栈顶。

image-20220313164505014.png

做题时我的思路首先是假设k很大很大,远大于nums.length。 那么显然此时必然能取到nums数组的最大值。

举个例子,比如k = nums.length + 1. 那么就可以把所有数都删除,然后最后第k步把最大的数放到栈顶。

如果k = nums.length + 2。 只要nums.length 不为1的话我们也可以把最大的数放大栈顶

如果k很大,我们就可以先把所有数删除,随便取一个数不停删除和放栈顶,直至最后一步把最大的数放到栈顶。

接着,我继续想,nums.length = 1应该也是个边界的coner case。我一开始以为当nums.length = 1 && k == 1 才是-1. 结果发现正确代码是:

if (nums.length == 1 && k % 2 == 1) {
    return -1;
}

凡是奇数都是-1.

这个条件我喜提一个WA

接着,讨论如果k < nums.length

一开始我想的是直接比较前k + 1个元素就行。把前k + 1个元素比较一遍取最大值。

但是像这种输入:

[91,98,17]
k = 2

最大值就只能是91.因为如果91,98都删除那栈顶就是17了,而如果98不删除,把91加到栈顶那才是最大值,显然,当下标 等于 k - 1的时候也是需要讨论的。正确代码:

// k < nums.length
int tmpMax = Integer.MIN_VALUE;
for (int i = 0; i < k - 1; i++) {
    tmpMax = Math.max(nums[i], tmpMax);
}
tmpMax = Math.max(tmpMax, nums[k]);

最后当我再次提交,发现还有最后一个case没法过,显示通过了194/ 195,并且最后的输入在比赛中不显示出来。此时时间还剩12分钟。

再次检查了一下条件,分析各种coner case。

1.k = 0 的时候

2.nums.length = 1的时候

3.k < nums.length

确信这里这里应该也没错

于是锁定在k= nums.length的时候,自己想了个例子:

[4,3,2,5]
k = 4

此时一测发现返回5。其实是不对的,因为当删除到5的时候,如果继续删除那么栈就为空了。所以只能删除前面k - 1个数。取前k - 1个数的最大值。

最终提交的代码:

public int maximumTop(int[] nums, int k) {
    if (nums.length == 1 && k % 2 == 1) {
        return -1;
    }
    if (k == 1 && nums.length > 1) {
        return nums[1];
    }
    int max = Integer.MIN_VALUE;
    for (int i = 0; i < nums.length; i++) {
        max = Math.max(max, nums[i]);
    }

    if (k > nums.length) {
        return max;
    }

    if (k == nums.length) {
        int max1 = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length - 1; i++) {
            max1 = Math.max(max1, nums[i]);
        }
        return max1;
    }

    // k < nums.length
    int tmpMax = Integer.MIN_VALUE;
    for (int i = 0; i < k - 1; i++) {
        tmpMax = Math.max(nums[i], tmpMax);
    }
    tmpMax = Math.max(tmpMax, nums[k]);
    return tmpMax;
}

比较挫,还有待加强。继续刷题!