每日两题--2021/11/29

这篇博客探讨了两个编程问题:一是如何计算马戏团中最多能叠多少人,通过寻找数组的最长升序排列解决;二是如何确定最后剩余石头的重量,采用排序和迭代方法不断减少石头的重量。这两个问题都涉及到了排序和优化策略的应用。
摘要由CSDN通过智能技术生成

面试题 17.08. 马戏团人塔

描述

有个马戏团正在设计叠罗汉的表演节目,一个人要站在另一人的肩膀上。出于实际和美观的考虑,在上面的人要比下面的人矮一点且轻一点。已知马戏团每个人的身高和体重,请编写代码计算叠罗汉最多能叠几个人。

思路

  1. 其实是寻找一个数组的最长升序排列,我们将身高,体重变成二维联合数组,按以一维(身高)元素升序排列,这样只要找到二维(体重)元素其最长的升序排列就行(需要注意,身高相同时,体重要降序排列,防止将同一身高加入)
  2. 假设dp是排列后的体重数组,res是目前最大长度
  3. 遍历体重数组,找出其元素在dp的位置(详见方法binarySearch()
  4. 如果找出的索引等于res,则res++,最后返回的res则是最多可以叠的人数

题解

class Solution {
    public int bestSeqAtIndex(int[] height, int[] weight) {
        int n = height.length;
        int[][] per = new int[n][2];
        for(int i = 0; i < n; i++){
            per[i] = new int[]{height[i], weight[i]};
        }

        //排序,根据二维数组第一维升序排序,如果第一维相等,第二维度降序排列
        Arrays.sort(per, (a, b) -> a[0] == b[0] ? b[1] - a[1] : a[0] - b[0]);

        int[] dp = new int[n];
        int res = 0;
        for(int i = 0; i < n; i++){
            //查找该数是否在dp中,并返回相关索引值(规则见该函数)
            int idx = Arrays.binarySearch(dp, 0, res, per[i][1]);
            if(idx < 0){
                idx = -(idx + 1);
            }
            dp[idx] = per[i][1];
            //相等说明叠上,长度加1
            if(idx == res){
                res++;
            }
        }

        return res;
    }
}

1046. 最后一块石头的重量

描述

有一堆石头,每块石头的重量都是正整数。
每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:
如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0。

思路

  1. 升序排列
  2. 取最大两个数相减,如果为0,则跳过,不为0,则数组长度减1,将差值加入到数组最后
  3. 重新排列求值,直到n小于等于1
  4. 最后n为0返回0,否则返回stones[0]

题解

class Solution {
    public int lastStoneWeight(int[] stones) {
        int n = stones.length;
        while(n > 1){
            Arrays.sort(stones);
            int tmp = stones[n - 1] - stones[n - 2];
            if(tmp == 0){
                n = n - 2;
                continue;
            }
            n = n - 1;
            stones[n - 1] = tmp;
        }

        return n == 0 ? 0 : stones[0];
    }
}

拓展
最大堆 java真牛啊,库真多

class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> b - a);
        for (int stone : stones) {
            pq.offer(stone);
        }

        while (pq.size() > 1) {
            int a = pq.poll();
            int b = pq.poll();
            if (a > b) {
                pq.offer(a - b);
            }
        }
        return pq.isEmpty() ? 0 : pq.poll();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值