题目描述:

给你一个整数数组 piles ,数组 下标从 0 开始 ,其中 piles[i] 表示第 i 堆石子中的石子数量。另给你一个整数 k ,请你执行下述操作 恰好 k 次:

选出任一石子堆 piles[i] ,并从中 移除 floor(piles[i] / 2) 颗石子。
注意:你可以对 同一堆 石子多次执行此操作。 返回执行 k 次操作后,剩下石子的 最小 总数。 floor(x) 为 小于 或 等于 x 的 最大 整数。(即,对 x 向下取整)。   示例 1: 输入:piles = [5,4,9], k = 2
输出:12
解释:可能的执行情景如下:
- 对第 2 堆石子执行移除操作,石子分布情况变成 [5,4,5] 。
- 对第 0 堆石子执行移除操作,石子分布情况变成 [3,4,5] 。
剩下石子的总数为 12 。
示例 2: 输入:piles = [4,3,6,7], k = 3
输出:12
解释:可能的执行情景如下:
- 对第 2 堆石子执行移除操作,石子分布情况变成 [4,3,3,7] 。
- 对第 3 堆石子执行移除操作,石子分布情况变成 [4,3,3,4] 。
- 对第 0 堆石子执行移除操作,石子分布情况变成 [2,3,3,4] 。
剩下石子的总数为 12 。
  提示: 1 <= piles.length <= 105
1 <= piles[i] <= 104
1 <= k <= 105 来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-stones-to-minimize-the-total
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

1、要使最后剩余的石子数最少,那每次减少的应该是当前石头数目最多的一堆,问题转换为求数组中的最大值问题

2、首先明确最后要求的只是剩余的石头总数,所以顺序可以改变,那么就可以对数组中元素进行排序再找最大值。

3、排序的话就涉及到了排序算法:

  由于数组定义后不能修改大小,首先想到把数组转换为list或queue

  (1)List的父类是Collection,继承父类的排序方法,而Collection.sort()采用的排序算法是一种改进的归并排序,归并算法的时间复杂度是O(nlog n)

  (2)使用Queue构建大顶堆,使用优先级队列,比较实现的是Comparator接口。堆中添加元素时间复杂度O(log N)

4、采用优先级队列构造大顶堆,每次取堆顶元素,减少一半后再加入堆中,循环k次得到最后的堆

5、将队列中所有元素相加得到最后结果。

public class RemoveStone {
//元素可以改变顺序!!超时!!
public int minStoneSum(int[] piles, int k) {
for(int i = 0; i < k; i++){
int max_number = 0;//当前轮最大的数值
int max_number_index = 0;//当前值最大的下标
for(int j = 0; j < piles.length; j++ ){
if(piles[j] > max_number){
max_number_index = j;
max_number = piles[j];
}
}
//去除当前值最的number的一半
piles[max_number_index] -= (int) Math.floor(piles[max_number_index]/2);
}
int sum = 0;
for(int i = 0; i < piles.length; i++){
sum += piles[i];
}
return sum;
} public int minStoneSum1(int[] piles, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>((a,b) -> b-a);//构建大顶堆
//将piles中元素入队
for(int i = 0; i < piles.length; i++){
pq.add(piles[i]);
}
//取堆顶元素减少一半并且重新放会堆中,循环k次
//堆添加元素时间复杂度O(log N)
for(int j = 0; j < k; j++){
int top_que = pq.poll();
top_que -= Math.floor(top_que/2.0);
pq.add(top_que);
}
//计算和
int sum = 0;
for(Integer q: pq){
sum += q;
}
return sum;
}
public int minStoneSum2(int[] piles, int k) {
List<Integer> piles_list = new ArrayList<>();
//将数组转换为list 超时!!
for(int i = 0; i< piles.length;i++){
piles_list.add(piles[i]);
} //Collection.sort()采用的排序算法是一种改进的归并排序,归并算法的时间复杂度是O(nlog n)
for(int j = 0; j < k; j++){
piles_list.sort((a,b)->b-a);//先对list进行倒序排序
piles_list.set(0, piles_list.get(0)-(int) Math.floor(piles_list.get(0)/2.0));//设置第一个值减少原来的一半
}
int sum =0;
for(Integer q : piles_list){
sum += q;
}
return sum;
}
public static void main(String[] args) {
int[] piles = new int[]{4,3,6,7};
int k = 3;
RemoveStone rs = new RemoveStone();
int result = rs.minStoneSum2(piles, k);
System.out.println(result);
}
}

最新文章

  1. chrome 跨域设置
  2. python反射原理
  3. 【大数据】Linux下Storm(0.9版本以上)的环境配置和小Demo
  4. 学习zepto.js(原型方法)[2]
  5. (转,有改动)测试网页响应时间的shell脚本[需要curl支持]
  6. Android Studio 初使用
  7. CROC 2016 - Final Round [Private, For Onsite Finalists Only] C. Binary Table FWT
  8. 开源(免费)三维 GIS(地形,游戏)
  9. bzoj1833 digit
  10. POJ3186:Treats for the Cows(区间DP)
  11. MPMoviePlayerController 电影播放器—备用
  12. PHP与MySQL交互
  13. Flex4 Alert PopupManager 演示样本
  14. AppCan 双击返回按钮退出应用
  15. 2019 面试准备 - JS 防抖与节流 (超级 重要!!!!!)
  16. BZOJ5322: [JXOI2018]排序问题
  17. Windows 安装 Go语言开发环境以及使用
  18. 关于tensorflow中tensorborad No dashboards are active for the current data set.的解决办法
  19. pyplot图像组件
  20. [Node.js]23. Level 4: Semantic versioning

热门文章

  1. 矩池云安装gdal五种解决方案
  2. 用Vue编写一个简单的仿Explorer文件管理器
  3. 2022:checking for Python executable &quot;python2&quot; in the PATH
  4. 【死磕NIO】— 跨进程文件锁:FileLock
  5. 权限命令 vi编辑器 命令模式 使用技巧
  6. openEuler网络配置+换源+桌面环境ukui等基本环境部署
  7. eclipse中的项目如何打成war包
  8. Nginx 静态文件服务
  9. ansible 三配置和命令集
  10. Android中的Coroutine协程原理详解