zoukankan      html  css  js  c++  java
  • [GeeksForGeeks] Maximum Length Chain of Pairs

    You are given n pairs of numbers. In every pair, the first number is always smaller than the second number. A pair (c, d) can follow another pair (a, b) if b < c. Chain of pairs can be formed in this fashion. Find the longest chain which can be formed from a given set of pairs. 

    For example, if the given pairs are {{5, 24}, {39, 60}, {15, 28}, {27, 40}, {50, 90} }, then the longest chain that can be formed is of length 3, and the chain is {{5, 24}, {27, 40}, {50, 90}}

    Solution 1. Dynamic Programming, O(n^2) runtime

    This problem looks similar with the Longest Increasing Subsequence but not quite the same. In LIS, the sequence's relative order is given and can not be changed.

    In this problem,  we are only given some pairs of numbers and no enforced order, we can rearrange their relative order to get the longest chain.

    Algorithm:

    1. sort the given pairs either by their first numbers or second numbers. Doing this reduces this problem to Longest Increasing Subsequence. 

    2.  The LIS problem can be solved using recursion or dynamic programming. 

     1 import java.util.ArrayList;
     2 import java.util.Arrays;
     3 import java.util.Comparator;
     4 
     5 class Pair {
     6     int first;
     7     int second;
     8     Pair(int first, int second) {
     9         this.first = first;
    10         this.second = second;
    11     }
    12     void display() {
    13         System.out.println(this.first + ", " + this.second);
    14     }
    15 }
    16 public class MaxLenChain {
    17     private int max = 0;
    18     public int getLongestChainRecursion(Pair[] pairs) {
    19         if(pairs == null || pairs.length == 0) {
    20             return 0;
    21         }
    22         Comparator<Pair> comp = new Comparator<Pair>(){
    23             public int compare(Pair p1, Pair p2) {
    24                 return p1.second - p2.second;
    25             }
    26         };
    27         Arrays.sort(pairs, comp);
    28         for(int i = 0; i < pairs.length; i++) {
    29             recursionHelper(pairs, i);
    30         }
    31         return max;
    32     }
    33     private int recursionHelper(Pair[] pairs, int endIdx) {
    34         int len = 1;
    35         for(int j = 0; j < endIdx; j++) {
    36             if(pairs[j].second < pairs[endIdx].first) {
    37                 len = Math.max(len, recursionHelper(pairs, j) + 1);
    38             }
    39         }
    40         if(len > max) {
    41             max = len;
    42         }
    43         return len;
    44     }
    45     public int getLongestChainDp(Pair[] pairs) {
    46         Comparator<Pair> comp = new Comparator<Pair>(){
    47             public int compare(Pair p1, Pair p2) {
    48                 return p1.second - p2.second;
    49             }
    50         };
    51         Arrays.sort(pairs, comp);
    52         ArrayList<Pair> longestChain = new ArrayList<Pair>();
    53         int[] LcEndAt = new int[pairs.length];
    54         int max = 0; int maxIdx = -1;
    55         for(int i = 0; i < pairs.length; i++) {
    56             LcEndAt[i] = 1;
    57             for(int j = 0; j < i; j++) {
    58                 if(pairs[j].second < pairs[i].first) {
    59                     LcEndAt[i] = Math.max(LcEndAt[i], LcEndAt[j] + 1);
    60                 }
    61             }
    62             if(LcEndAt[i] > max) {
    63                 max = LcEndAt[i];
    64                 maxIdx = i;
    65             }
    66         }
    67         int maxLen = max;
    68         while(maxLen > 0) {
    69             longestChain.add(pairs[maxIdx]);
    70             maxLen--;
    71             for(int i = 0; i < maxIdx; i++) {
    72                 if(LcEndAt[i] == maxLen){
    73                     maxIdx = i;
    74                     break;
    75                 }
    76             }
    77         }
    78         for(int i = longestChain.size() - 1; i >= 0; i--) {
    79             longestChain.get(i).display();
    80         }
    81         return max;
    82     }
    83     public static void main(String[] args) {
    84         Pair p1 = new Pair(5,24);
    85         Pair p2 = new Pair(39,60);
    86         Pair p3 = new Pair(15,28);
    87         Pair p4 = new Pair(27,40);
    88         Pair p5 = new Pair(50,90);
    89         Pair[] pairs = {p1,p2,p3,p4,p5};
    90         /*Pair p1 = new Pair(90,100);
    91         Pair p2 = new Pair(70,80);
    92         Pair p3 = new Pair(50,60);
    93         Pair p4 = new Pair(30,40);
    94         Pair[] pairs = {p1,p2,p3,p4};*/
    95         MaxLenChain test = new MaxLenChain();
    96         System.out.println(test.getLongestChainDp(pairs));
    97     }
    98 }

    Solution 2. Greedy Algorithm(Activity Selection Problem), O(n*logn) runtime

    This problem is also a variation of Activity Selection Problem and can be solved in O(n*logn) runtime. To solve it as an activity selection problem,

    consider the first element of a pair as start time in activity selection problem, and the second element as end time. 

    Algorithm:

    1. sort the activities according to their finishing time.

    2. select the first activity from the sorted array as the first activity in the optimal solution.

    3. do the following for remaining activities in the sorted array.

        pick the next activity whose finish time is the smallest among the remaining activities and its start time is >= the finish time of previously selected activity.

    Proof of correctness

    Let the give set of activities be S = {1, 2, 3, ..n} and activities be sorted by finish time. The greedy choice is to always pick activity 1. How come the activity 1 always provides one of the optimal solutions. We can prove it by showing that if there is another solution B with first activity other than 1, then there is also a solution A of same size with activity 1 as first activity. Let the first activity selected by B be k, then there always exist A = {B – {k}} U {1}.(Note that the activities in B are independent and k has smallest finishing time among all. Since k is not 1, finish(k) >= finish(1)).

     1 public int getLongestChainGreedy(Pair[] pairs) {
     2     Comparator<Pair> comp = new Comparator<Pair>(){
     3         public int compare(Pair p1, Pair p2) {
     4             return p1.second - p2.second;
     5         }
     6     };
     7     Arrays.sort(pairs, comp);
     8     int maxLen = 1; int prevPicked = 0, currIdx = 1;
     9     while(currIdx < pairs.length) {
    10         if(pairs[prevPicked].second <= pairs[currIdx].first) {
    11             maxLen++;
    12             prevPicked = currIdx;
    13         }
    14         currIdx++;
    15     }
    16     return maxLen;
    17 }

    The same greedy algorithm can also be implemented by sorting for start time and traverse backward. The last activity whose start time is the biggest is always in one of the optimal solution.

    This problem is similar but not the same with Number of Airplanes in the sky.

    Similarity: both problems are given activities with a start and end time.

    Difference: This problem looks for the max result "horizontally", Number of Airplanes in the sky looks for the max result "vertically".

    This problems looks for the most activities that does not have time overlap;

    Number of Airplanes in the sky looks for at any time, the most number of activities that can happen at the same time. 

    Related Problems 

    [LintCode] Number of Airplanes in the Sky

  • 相关阅读:
    Redis哨兵(Sentinel)模式
    一个http请求就是一个线程吗,java的服务是每收到一个请求就新开一个线程来处理吗
    Redis 快速入门
    Redis 持久化之RDB和AOF
    Junit 入门使用教程 转自:http://www.cnblogs.com/ysocean/p/6889906.html
    Spring里PropertyPlaceholderConfigurer类的使用 转自:https://www.cnblogs.com/huqianliang/p/5673701.html
    Apache Commons Codec 编码/解码 (Base64/MD5/SHA1/SHA256等算法) 转自https://blog.csdn.net/hbtj_1216/article/details/52813741
    hive中时间日期函数的使用
    关于mat函数
    strip 和split
  • 原文地址:https://www.cnblogs.com/lz87/p/7461297.html
Copyright © 2011-2022 走看看