leetcode354. 俄羅斯套娃信封問題(最長遞增子序列的應用) 困難

題目:
在這裏插入圖片描述
分析:
這是一道解法很騷的題目,是最長遞增子序列的應用
直接說解法,先進行排序,長度升序,高度降序排序
然後把高度全去下來找最長遞增子序列
這麼做的正確性:
首先套信封是嚴格長和高都要小於才能套進去的,不能等於
找到最長遞增子序列的正確性在於,那麼長度必定不相等,因爲如果長度相等,那麼按高度降序排序,不可能出現遞增,那麼只要出現遞增,那麼前一個的長度必定小於後一個,能套進信封

代碼:

class Solution {
    public int maxEnvelopes(int[][] envelopes) {
        if(envelopes == null){
            return 0;
        }
        Arrays.sort(envelopes, (int[] a, int[] b)->{
            if(a[0] == b[0]){
                return b[1] - a[1];
            }else{
                return a[0] - b[0];
            }
        });
        int len = envelopes.length;
        int[] heights = new int[len];
        //把排序後的高度加入數組
        for(int i = 0; i < len; i++){
            heights[i] = envelopes[i][1];
        }
        //求最大遞增序列
        return bestResolutionOfLIS(heights);
    }

    //最長遞增子序列最優解,用二分
    static int bestResolutionOfLIS(int[] nums){
        if (nums == null || nums.length == 0){
            return 0;
        }
        int maxLen = 0;
        int len = nums.length;
        int[] ends = new int[len];
        //此時ends沒有有效區,爲-1
        int validIndex = -1;
        int[] dp = new int[len];
        for (int i = 0; i < len; i++) {
            int res = firstBigger(ends, validIndex, nums[i]);
            if (res == -1){
                //沒有找到
                validIndex++;
                ends[validIndex] = nums[i];
                dp[i] = validIndex + 1;
            }else {
                //找到,更新值
                ends[res] = nums[i];
                dp[i] = res + 1;
            }
            maxLen = Math.max(maxLen, dp[i]);
        }
        return maxLen;
    }

    static int firstBigger(int[] arr, int end, int target){
        int l = 0;
        int r = end;
        int result = -1;
        while (l <= r){
            int m = (l + r) / 2;
            if (arr[m] > target){
                result = m;
                r = m - 1;
            }else if (arr[m] < target){
                l = m + 1;
            }else {
                return m;
            }
        }
        return result;
    }
}

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章