• leetcode 1962. 移除石子使总数最小


    题目描述:

    给你一个整数数组 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);
        }
    }
    唯有热爱方能抵御岁月漫长。
  • 相关阅读:
    (计算几何 线段判交) 51nod1264 线段相交
    (线段判交的一些注意。。。)nyoj 1016-德莱联盟
    Spring的事务管理
    Spring JDBC模版以及三种数据库连接池的使用
    Springmvc架构
    AspectJ用注解替换xml配置
    在eclipse中spring的xml配置文件标签中class路径全限定名自动提示设置
    给属性字符串添加下划线
    检测程序是否打开
    系统目录
  • 原文地址:https://www.cnblogs.com/syq816/p/15302251.html
Copyright © 2020-2023  润新知