• 【每日一题】2558. 从数量最多的堆取走礼物-2023.10.28


    题目:

    2558. 从数量最多的堆取走礼物

    给你一个整数数组 gifts ,表示各堆礼物的数量。每一秒,你需要执行以下操作:

    • 选择礼物数量最多的那一堆。
    • 如果不止一堆都符合礼物数量最多,从中选择任一堆即可。
    • 选中的那一堆留下平方根数量的礼物(向下取整),取走其他的礼物。

    返回在 k 秒后剩下的礼物数量

    示例 1:

    输入:gifts = [25,64,9,4,100], k = 4
    输出:29
    解释: 
    按下述方式取走礼物:
    - 在第一秒,选中最后一堆,剩下 10 个礼物。
    - 接着第二秒选中第二堆礼物,剩下 8 个礼物。
    - 然后选中第一堆礼物,剩下 5 个礼物。
    - 最后,再次选中最后一堆礼物,剩下 3 个礼物。
    最后剩下的礼物数量分别是 [5,8,9,4,3] ,所以,剩下礼物的总数量是 29 。
    

    示例 2:

    输入:gifts = [1,1,1,1], k = 4
    输出:4
    解释:
    在本例中,不管选中哪一堆礼物,都必须剩下 1 个礼物。 
    也就是说,你无法获取任一堆中的礼物。 
    所以,剩下礼物的总数量是 4 。
    

    提示:

    • 1 <= gifts.length <= 103
    • 1 <= gifts[i] <= 109
    • 1 <= k <= 103

    解答:

    方法1:

    暴力法:先排序,再将最大的那个进行平方

    方法2:堆

    代码:

    方法1:

    1. class Solution {
    2. public long pickGifts(int[] gifts, int k) {
    3. int n=gifts.length;
    4. for(int i=0;i<k;i++){
    5. Arrays.sort(gifts);
    6. gifts[n-1]=(int)Math.floor(Math.sqrt(gifts[n-1]));
    7. }
    8. long sum=0;
    9. for(int i=0;i<n;i++){
    10. sum+=gifts[i];
    11. //System.out.println(gifts[i]);
    12. }
    13. return sum;
    14. }
    15. }

    方法2:

    1. class Solution {
    2. int[] heap = new int[10010];
    3. int sz = 0;
    4. public long pickGifts(int[] gs, int k) {
    5. for (int x : gs) add(-x);
    6. while (k-- > 0) add(-(int)Math.sqrt(-pop()));
    7. long ans = 0;
    8. while (sz != 0) ans += -heap[sz--]; // 没必要再维持堆的有序, 直接读取累加
    9. return ans;
    10. }
    11. void swap(int a, int b) {
    12. int c = heap[a];
    13. heap[a] = heap[b];
    14. heap[b] = c;
    15. }
    16. void up(int u) {
    17. // 将「当前节点 i」与「父节点 i / 2」进行比较, 若父节点值更大, 则进行交换
    18. int fa = u / 2;
    19. if (fa != 0 && heap[fa] > heap[u]) {
    20. swap(fa, u);
    21. up(fa);
    22. }
    23. }
    24. void down(int u) {
    25. // 将当「前节点 cur」与「左节点 l」及「右节点 r」进行比较, 找出最小值, 若当前节点不是最小值, 则进行交换
    26. int cur = u;
    27. int l = u * 2, r = u * 2 + 1;
    28. if (l <= sz && heap[l] < heap[cur]) cur = l;
    29. if (r <= sz && heap[r] < heap[cur]) cur = r;
    30. if (cur != u) {
    31. swap(cur, u);
    32. down(cur);
    33. }
    34. }
    35. void add(int x) {
    36. heap[++sz] = x;
    37. up(sz);
    38. }
    39. int peek() {
    40. return heap[1];
    41. }
    42. int pop() {
    43. int ans = peek();
    44. heap[1] = heap[sz--];
    45. down(1);
    46. return ans;
    47. }
    48. }

    结果:

  • 相关阅读:
    spring中的Lifecycle
    如何在Thymeleaf 模板中使用片段Fragments
    [C++](10)C++的string类如何实现?
    selenium元素定位---ElementClickInterceptedException(元素点击交互异常)解决方法
    spring security auth2.0实现
    五、hdfs常见权限问题
    交易猫链接源码搭建/带教程
    数字化打开第二增长曲线,华为总结运营商云转型三大场景
    SpringBoot配置文件
    Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单
  • 原文地址:https://blog.csdn.net/weixin_45142381/article/details/134092453