【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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章