2233:K 次增加后的最大乘积
2022-04-12 本文已影响0人
nobigogle
题意
给你一个非负整数数组 nums 和一个整数 k 。每次操作,你可以选择 nums 中任一元素并将它增加 1 。
请你返回至多 k 次操作后,能得到的 nums的 最大乘积 。由于答案可能很大,请你将答案对 取余后返回。
分析
1: 第一个想法是用DFS去解,每一位都可能加次。
2: 如果两个数,我们想让获得最大值,怎么处理?假设,操作一次,我们应该将,因为将才是其实相当于增加了一个,而正式其中的较大值。相反如果我们将,则整个结果相当于增加了一个,并不是最大值。
例如:
增加B:【增加4】
增加A:【增加3】
题解
DFS
class Solution {
long ans = Long.MIN_VALUE;
public int maximumProduct(int[] nums, int k) {
maximumProductSub(nums, k, 0, 1);
return (int) ans;
}
public void maximumProductSub(int[] nums, int k, int index, long tempAns) {
if (index == nums.length) {
if (tempAns > ans) {
ans = tempAns;
}
return;
}
for (int j = 0; j <= k; j++) {
maximumProductSub(nums, k - j, index + 1, tempAns * (nums[index] + j) % 1000000007);
}
}
}
这是个有问题的解法,没有很好的处理越界的问题,因此会出现由于错过错误答案,没能全部通过测试用例。
这个问题出在了,每次都对结果进行取余,因此就不能获取到真正的最大值。
如果需要取余的数是,第一次获取的结果是:,比小,,但是当结果为,比大,,再和5进行比较,会出现的错误判断,错过了最大值。
需要注意只需要在最终的结果取余就行
DFS2
class Solution {
long ans = Long.MIN_VALUE;
public int maximumProduct(int[] nums, int k) {
maximumProductSub(nums, k, 0, 1);
return (int) (ans%1000000007);
}
public void maximumProductSub(int[] nums, int k, int index, long tempAns) {
if (index == nums.length) {
if (tempAns > ans) {
ans = tempAns;
}
return;
}
for (int j = 0; j <= k; j++) {
maximumProductSub(nums, k - j, index + 1, tempAns * (nums[index] + j) );
}
}
}
这个没有出现错误答案,但是出现了运行时间超时的异常,只能证明DFS不符合这个题的解法。
优先队列
class Solution {
public int maximumProduct(int[] nums, int k) {
PriorityQueue<Integer> queue = new PriorityQueue<Integer>();
for(int num:nums){
queue.offer(num);
}
while(k>0){
int element = queue.poll();
element = element+1;
queue.offer(element);
k--;
}
long ans = 1;
while(queue.size()!=0){
ans = ans*queue.poll();
ans = ans%(1000000007);
}
return (int)ans;
}
}