题目是:
“曾经有两次消除的机会摆在我面前,我却没有珍惜……”牛牛回忆道。
牛牛正在玩一款全新的消消乐游戏。这款游戏的主体是由一列列的方块构成,牛牛的目标就是要尽量消除这些方块。
每次操作,牛牛可以选择某个高度 x,将所有高度大于等于 x 的那些列全部消除 x 个方块,随后方块会下落,以填补消除造成的空白。
牛牛这一局的发挥极佳,眼看就要破纪录了,却发现自己只剩下了两次消除机会。
为了不错失这千载难逢的机会,他决定写个程序来算出最优解。
简明题意:
给定一个数组 nums,其中有 n 个非负整数。你的目的是进行两次操作,使得数组的元素之和最小。
每次操作形如:任选一个整数 x ,将数组中所有
示例1
输入
[2, 1, 3]
输出
0
说明
初始数组为 [2, 1, 3]。
先选择 x = 2,则所有大于等于 2 的元素减去 2 ,变成 [0, 1, 1]。
再选择 x = 1,则所有大于等于 1 的元素减去 1 ,变成 [0, 0, 0]。
所以数组元素之和的最小值为 0。
我的解法
import java.util.*; public class Solution { /** * 返回两次操作后,数组元素之和的最小值 * @param nums int整型一维数组 这你你需要操作的数组 * @return long长整型 */ public long minimumValueAfterDispel (int[] nums) { // write code here Arrays.sort(nums); long sum = 0;//记录整个数组的和 long max = 0;//记录能够减去的最大值 for(int j=0;j){ sum += nums[j]; int index1 = j; int index2 = j; int index3 = j; for(int i=0;i<=j;i++){ while(index1 > 0 && nums[index1-1] >= nums[j]-nums[i]){ index1--; } while(index2 > i && nums[index2-1] >= nums[j]-nums[i]){ index2--; } while(index3 < nums.length && (long)nums[index3] < (long)nums[i]+nums[j]){ index3++; } /* 假设两次减去的数为a,b(a*/ long tmp1 = (i-index1)*((long)nums[j]-nums[i]) + (j-i)*(long)nums[i] + (nums.length-j)*(long)nums[j]; long tmp2 = (index2-i)*((long)nums[i]) + (j-index2)*((long)nums[j]-nums[i]) + (nums.length-j)*(long)nums[j]; long tmp3 = (j-i)*(long)nums[i] + (index3-j)*(long)nums[j] + (nums.length-index3)*((long)nums[i]+nums[j]); max = Math.max(max,tmp1); max = Math.max(max,tmp2); max = Math.max(max,tmp3); } } return sum - max; } }
大家有什么好的解法也可以在评论区说出来
最后我把我收集的各大厂经典高频面试题和Java高级进阶、架构师视频教程送予大家。部分资料如下图所示:
获取地址: