题目描述:

给你一个整数数组 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);
}
}

leetcode 1962. 移除石子使总数最小的更多相关文章

  1. LeetCode:移除K位数字【402】

    LeetCode:移除K位数字[402] 题目描述 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. nu ...

  2. LeetCode初级算法--设计问题02:最小栈

    LeetCode初级算法--设计问题02:最小栈 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...

  3. [Winform]关闭窗口使其最小化

    摘要 在用户操作关闭窗口的时候,而不是真正的关闭,使其最小化到任务栏,或者托盘. 核心代码 关闭操作,使其最小化到任务栏. private void Form1_Load(object sender, ...

  4. o(1)取b > a,且b的二进制中1的个数等于a二进制中1的个数,且使b最小

    给你一个uint32 a,让你找到另一个uint32 b,使b > a,且b的二进制中1的个数等于a二进制中1的个数.且使b最小.(数据保证可出) 1 因为1的个数不变,所以必然大于n+lowb ...

  5. 【LeetCode题解】530_二分搜索树的最小绝对值差

    目录 [LeetCode题解]530_二分搜索树的最小绝对值差 描述 方法一.中序遍历二分搜索树 思路 Java 代码 Python 代码 [LeetCode题解]530_二分搜索树的最小绝对值差 描 ...

  6. windows vbs启动多个应用程序并使程序最小化(显示桌面)

      windows vbs启动多个应用程序并使程序最小化(显示桌面) CreationTime--2018年7月26日11点18分 Author:Marydon 1.应用场景 每天开机后,都需要打开平 ...

  7. 前端与算法 leetcode 27.移除元素

    目录 # 前端与算法 leetcode 27.移除元素 题目描述 概要 提示 解析 算法 @(目录) # 前端与算法 leetcode 27.移除元素 题目描述 27.移除元素 概要 题目本身其实挺简 ...

  8. Leetcode(877)-石子游戏

    亚历克斯和李用几堆石子在做游戏.偶数堆石子排成一行,每堆都有正整数颗石子 piles[i] . 游戏以谁手中的石子最多来决出胜负.石子的总数是奇数,所以没有平局. 亚历克斯和李轮流进行,亚历克斯先开始 ...

  9. Leetcode:530. 二叉搜索树的最小绝对差

    Leetcode:530. 二叉搜索树的最小绝对差 Leetcode:530. 二叉搜索树的最小绝对差 Talk is cheap . Show me the code . /** * Definit ...

随机推荐

  1. 实用TCP协议(2):TCP 参数优化

    在了解 TCP 的基本机制后本文继续介绍 Linux 内核提供的链接队列.TW_REUSE.SO_REUSEPORT.SYN_COOKIES 等机制以优化生产环境中遇到的性能问题. 连接队列 Linu ...

  2. Typora笔记上传到博客

    Typora笔记上传到博客 Markdown是一种轻量级标记语言,排版语法简洁,让人们更多地关注内容本身而非排版.它使用易读易写的纯文本格式编写文档,可与HTML混编,可导出 HTML.PDF 以及本 ...

  3. Linux CentOS7.X-目录切换

    一.cd 命令 在Linux中,进行目录的切换需要使用cd命令. 二.Linux目录结构  三.Linux CentOS7中几个常用目录切换方式 1.cd usr 切换到当前目录下的usr目录. 2. ...

  4. 浅识 npm 与 cnpm

    npm是什么? Node Package(包) Manager(管理器) 的简称. 在 GitHub 还没有兴起的年代,前端是通过网址来共享代码.比如你想使用 jQuery,那么你点击 jQuery ...

  5. count()用法

  6. yum 安装的历史与撤销(yum history undo )

    我们可以使用yum history 来查看yum的历史记录 想撤销安装则输入 yum history undo <ID号> 即可撤销yum的安装/升级

  7. BSOJ6388题解

    看上去就很神秘...考虑建出图论模型. 我们将一张牌的两面 \(a,b\) 连一条边. 考虑一个连通块的意义是什么. 边是一张牌,容易发现,如果连通块是一棵树,那么选择一个根节点相当于可以打出除了根节 ...

  8. Export大数据量导出和打包

    项目需求 ​ 导出生成大批量数据的文件,一个Excel中最多存有五十万条数据,查询多余五十万的数据写多个Excel中.导出完成是生成的多个Excel文件打包压缩成zip,而后更新导出记录中的压缩文件路 ...

  9. springcloud学习01-用intellij idea搭建Eureka服务

    0.配置intellij idea工具:https://www.cnblogs.com/wang-liang-blogs/p/12060702.html 1.使用maven构建工具构建主工程项目. 1 ...

  10. 统计分析— 1.SPSS数据编辑窗口 输出窗口 语法窗口

    第一课-SPSS窗口 一 数据编辑窗口(Data Editor) 二 输出窗口(Output Viewer ) 三 语法窗口(Syntax Editor):针对中高级用户,有些操作可以通过输入代码的方 ...