二维递增子序列

来源:互联网 发布:网游加速器 for mac 编辑:程序博客网 时间:2024/06/06 21:32

题目:

给定一个 N*2的二维数组,看作是一个个二元组,例如[[a1,b1],[a2,b2],[a3,b3]],规定:一个如果想把二元组甲放在二元组乙上,甲中的a值必须大于乙中的a值,甲中的b

值必须大于乙中的 b 值。如果在二维数组中随意选择二元组,请问二元组最多可以往上摞几个?

例如:[[5,4],[6,4],[6,7],[2,3]],最大数量可以摞3个,[2,3] => [5,4] => [6,7]要求:实现时间复杂度O(N*logN)的解法 

/*

* 根据一维最长递增子序列思路求解  一维最长递增子序列

* 1:先排序:规则如下

* 按照x升序排列 如果x相等按照y降序排序 因为不能这样摞[6,4]=》[6,7],所以排序后[6,7]=》[6,4]

* 2:对y求最长递增子序列

* 时间复杂度nlogn*/

代码:

/** * Created by xq on 16/4/13. */public class Solution {/** 根据一维最长递增子序列思路求解* 1:先排序:规则* 按照x升序排列 如果x相等按照y降序排序* 2:对y求最长递增子序列* 时间复杂度nlogn*/    static class Node{        int x;        int y;        public Node(int x,int y){            this.x = x;            this.y = y;        }        @Override        public String toString() {            return "{" +                    "x=" + x +                    ", y=" + y +                    '}';        }    }    private static Comparator<Node> comparator = new Comparator<Node>() {        @Override        public int compare(Node l, Node r) {            if (r.x>l.x){//按照x升序排列                return -1;            } else if (r.x<l.x){                return 1;            } else {//按照y降序排列                if (r.y>l.y){                    return 1;                } else {                    return -1;                }            }        }    };    //{x=2, y=3}{x=4, y=7}{x=5, y=7}{x=5, y=4}{x=6, y=7}{x=6, y=4}    public static void main(String args[]){        Solution  s = new Solution();        Node n1 =  new Node(2,3);        Node n2 =  new Node(4,7);        Node n3 =  new Node(5,7);        Node n4 =  new Node(5,4);        Node n5 =  new Node(6,7);        Node n6 =  new Node(6,4);        List<Node> list = new ArrayList<>();        List<Node> help = new ArrayList<>();        list.add(n1);        list.add(n2);        list.add(n3);        list.add(n4);        list.add(n5);        list.add(n6);        Collections.sort(list,comparator);        System.out.println("排序后的结果:");        for (Node n:list) {            System.out.print(n.toString());        }        System.out.println();        int flag = 0;        for (Node n:list) {            if (help.isEmpty()||help.get(help.size()-1).y<n.y){                help.add(n);            }else {                    int l = 0;                    int r = help.size();                    while(l<=r){//二分法                        int mid = l+((r-l)>>1);                        if(n.y==help.get(mid).y){//如果已经存在就不添加                            flag = 1;                            break;                        }                       else if(n.y>help.get(mid).y){                           l = mid+1;                        } else {                           r = mid-1;                       }                    }                System.out.println("r: "+ r);                System.out.println("l: "+ l);                if(flag==1){                  flag=0;                }else{                    Node remove = help.remove(l);                    help.add(l,n);                }            }        }        System.out.println("最大个数:"+help.size());        for (Node n:help) {            System.out.print(n.toString()+" ");        }    }

结果:


题目来源:牛课网


0 0