2024美团秋招第一场笔试

解题思路:

这道题的难点在于计算Mex以及每次执行一次只删除第一个数组中的数字时,要及时更新Mex。我们假设不执行操作1,直接删除数组中全部数字的花费,此时就是Mex(a)=6,输入的花费系数k=3,此时totalCost = 3 * 6 = 18,因此首先假设最低花费minCost = totalCost = 18。然后计算MEX,即使用while()循环,查看哈希表中是否存在关键字MEX(为什么用哈希表存数字,下面说。),如果MEX包含在哈希表中则MEX++,因为题目中已经说了,Mex(a)即在数组中未出现过的最小非负整数。最后是计算最小成本,因此最小成本是从总成本(每次执行操作1后的成本基本上都是不一样的)和直接删除整个数组(操作2)的花费成本相比较得出的最小值。

接着说一下为什么要使用集合,因为题目中没有特别说明数组中没有重复的值,即可能存在重复的数组元素,利用哈希表中的键值关系,用键来存储每个数组元素出现的次数,用值来表示该数组元素的值。最后一定要用Long类型的变量,用int类型的会报错。

下面是Java代码:

package jxkjsfdx.lgq;
import java.util.*;

public class Demo01 {
    public static void main(String[] args) {
        removeArray();

    }

    public static void removeArray() {
        Scanner scanner = new Scanner(System.in);
        long t = scanner.nextLong();

        while (t-- > 0) {
            long n = scanner.nextLong(); // 数组长度
            long k = scanner.nextLong(); // 删除整个数组的花费系数
            long x = scanner.nextLong(); // 单个删除的花费

            Map<Long, Long> hashMap = new HashMap<>();
            long[] a = new long[(int) n];

            for (long i = 0; i < n; i++) {
                a[(int) i] = scanner.nextLong();
                // 统计数组中每个元素出现的次数;如果元素已经存在于 hashMap 中,就增加其计数;如果不存在,则从0开始计数。
                hashMap.put(a[(int) i], hashMap.getOrDefault(a[(int) i], 0L) + 1);
            }

            // 计算MEX
            long minMiss = 0;
            while (hashMap.containsKey(minMiss)) {
                minMiss++;
            }

            long totalCost = k * minMiss; // 一开始就删除整个数组
            long minCost = totalCost;
            for (long i = 0; i < n; i++) {
                long currentValue = a[(int) i];
                System.out.println("当前MEX是:" + minMiss);
                System.out.println("当前总花费是:" + totalCost);

                // 更新 hashMap
                if (hashMap.get(currentValue) > 1) {
                    hashMap.put(currentValue, hashMap.get(currentValue) - 1);
                } else {
                    hashMap.remove(currentValue);
                }

                // 计算新的 mex
                minMiss = 0;   // 每次将minMiss置0,求出在不同的操作1下的MEX
                while (hashMap.containsKey(minMiss)) {
                    minMiss++;
                }

                // 计算当前结果
                minCost = Math.min(totalCost, (i + 1) * x + k * minMiss); // (i + 1) 是当前删除的元素数量
            }
            // 输出最小成本
            System.out.println("最小成本是:" + minCost);
        }

        scanner.close();
    }
}

全部评论

相关推荐

1.&nbsp;面试官先做自我介绍(少见),然后让我做自我介绍2.&nbsp;我看你本科是华南农业大学的,你也是广东人吗,因为我是广州人3.&nbsp;你写的两个项目是学习练手呢,还是上线使用的?4.&nbsp;挑一个你最熟悉的项目,说一下你遇到的难点以及解决思路5.&nbsp;为什么项目中同时使用了mysql和mongodb,选型上有什么考量的吗?6.&nbsp;了解MongoDB的存储数据结构吗7.&nbsp;用MySQL存储结构化数据,MongoDB存储非结构化数据,各自代表一个什么样的业务含义呢8.&nbsp;看你使用了redis的地理位置功能,你了解它的原理吗9.&nbsp;项目完成之后你怎么去验证它的可行性和功能的可用性呢10.&nbsp;RPC和HTTP的区别11.&nbsp;MySQL的存储引擎以及它的数据结构12.&nbsp;B+树,为什么比普通的二叉树高度小,查找性能比较高是怎么做到的,相比B树的优点13.&nbsp;MySQL的索引类型,索引在什么场景下会失效14.&nbsp;说一下HTTP的相关知识,HTTPS通过什么方式加密来达到安全的目的15.&nbsp;哪个环节会使用到这http和https协议,只借助这两个协议就能够达到安全加密的诉求了吗16.&nbsp;tcp建立过程,两次握手或四次握手可以吗,三次握手有什么缺点17.&nbsp;说一下你项目中使用的设计模式(我项目中没用,我可以说一下我熟悉的)18.&nbsp;手撕1:单例模式(饿汉式,懒汉式(加锁,双重检测锁)),加上synchronized为什么就线程安全了19.&nbsp;手撕2:动态规划:最大子数组和,(不会处理输入),写完后讲下思路20.&nbsp;反问:多久出结果,入职的话还需要学什么#秋招##字节##面试##后端#
投递字节跳动等公司10个岗位
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务