leetcode 646. Maximum Length of Pair Chain(最大链对的长度)

You are given n pairs of numbers. In every pair, the first number is always smaller than the second number.

Now, we define a pair (c, d) can follow another pair (a, b) if and only if b < c. Chain of pairs can be formed in this fashion.

Given a set of pairs, find the length longest chain which can be formed. You needn’t use up all the given pairs. You can select pairs in any order.

Example 1:
Input: [[1,2], [2,3], [3,4]]
Output: 2
Explanation: The longest chain is [1,2] -> [3,4]
Note:
The number of given pairs will be in the range [1, 1000].

给出几个对子,组成一个链,能组成链的要求是下一对的首数字要比上一对的尾数字要大
问链的最大长度

思路:
第一种,DP。
先要对所有pair的尾数字排序,排序后才能按顺序遍历pairs
加上新pair后链的长度=它之前的链长度(遍历它之前的) + 新pair是否能加入链
上面有遍历,在所以遍历的中取最大长度,最后返回dp[n-1]

    public int findLongestChain(int[][] pairs) {
        if(pairs == null || pairs.length == 0) {
            return 0;
        }
        
        int n = pairs.length;
        int[] dp = new int[n];
        
        Arrays.sort(pairs, new Comparator<int[]>() {
            public int compare(int[] p1, int[] p2) {
                return p1[1] - p2[1];
            }
        });
        
        dp[0] = 1;      
        for(int i = 1; i < n; i++) {
            for(int j = 0; j < i; j++) {
                int tmp = (pairs[i][0] > pairs[j][1]) ? 1 : 0;
                dp[i] = Math.max(dp[i], dp[j] + tmp);
            }
        }
        return dp[n-1];
    }

第二种,Greedy
其实也不需要遍历所有新pair之前的,因为每到一个新pair,能和之前组成链的就留下来,组不成的直接扔掉就好了。
这时候可以用一个stack保存能组成链的pairs,最后看stack的长度。
或者不用stack,每次就保留组成链的最后一个pair的尾数字,也就是整个链的末尾最大数字,只要下一个pair的首数字大于这个末尾的最大数字,它就能加入到链中。

    public int findLongestChain(int[][] pairs) {
        if(pairs == null || pairs.length == 0) {
            return 0;
        }
        
        int n = pairs.length;
        int result = 1;
                
        Arrays.sort(pairs, new Comparator<int[]>() {
            public int compare(int[] p1, int[] p2) {
                return p1[1] - p2[1];
            }
        });
        
        int end = pairs[0][1];
             
        for(int i = 1; i < n; i++) {
            if(pairs[i][0] > end) {
                result ++;
                end = pairs[i][1];
            }
        }
        return result;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值