【leetcode-38】【二分系列】面试题 17.08. 马戏团人塔

题目描述

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

示例:

输入:height = [65,70,56,75,60,68] weight = [100,150,90,190,95,110]
输出:6
解释:从上往下数,叠罗汉最多能叠 6 层:(56,90), (60,95), (65,100), (68,110), (70,150), (75,190)

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/circus-tower-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

  • 这里有一个问题,就是上一层要比下一层矮一点瘦一点,也就是说在身高相同的情况下,只能选一个最瘦的
  • 这道题就是求一个最长上升子序列,使得第i个比i-1个的体重小一点,身高矮一点。
  • 最长上升子序列有两种求法,动态规划和二分法
    • 动态规划的dp[i]指的是以数组中第i个元素结尾的最长上升序列的长度
    • 二分法的d[i]是单调递增数组,d[i]代表的是长度为i的上升子序列的最后一个元素的值
    • 首先应该对身高排序,如果升高一致,对体重进行倒序排序,这里参考了题解,人家通过构建二维数组,使用库函数巧妙地解决了这个问题
    • 对体重采用倒序排列,是为了在后续采用贪心+二分法,解决最长子串问题时,在身高相同的情况下,尽可能选择体重轻的那一个人。
    • 总结:这道题巩固了贪心+二分,促使我看了binarySearch的源码,为怎么实现多条件排序提供了套路

代码

class Solution {
    
    
    public int bestSeqAtIndex(int[] height, int[] weight) {
    
    
        if(height == null || weight == null || height.length == 0 || weight.length == 0 || weight.length != height.length) return 0;
        int[][] person = new int[height.length][2];
        for(int i = 0; i < height.length; i++){
    
    
            person[i] = new int[]{
    
    height[i], weight[i]};
        }
        Arrays.sort(person, (o1, o2) -> o1[0] == o2[0] ? o2[1] - o1[1] : o1[0] - o2[0]);
        int[] d = new int[height.length];
        d[0] = person[0][1];
        int len = 1;
        for(int i = 1; i < height.length; i++){
    
    
            int index = Arrays.binarySearch(d, 0, len, person[i][1]);
            if(index < 0){
    
    
                index = -(index + 1);
            }
            d[index] = person[i][1];
            if(index == len) ++len;
        }
        return len;
    }
}

猜你喜欢

转载自blog.csdn.net/u010659877/article/details/106162647
今日推荐