俄罗斯套娃问题(Java)

来源:互联网 发布:手机解压密码破解软件 编辑:程序博客网 时间:2024/04/30 00:31

问题,输入:第一行 n ,表示有n个套娃。之后n行,每行两个整数:分别表示宽和高。
只有宽和高都大于的才能嵌套。
输出:嵌套的最大层数。

一道笔试题,当时还不会LIS算法(最大上升子序列),没什么头绪,会了LIS就很简单了。
LIS算法分析:http://blog.csdn.net/lsjweiyi/article/details/70871825

两种方法:

第一种:

import java.util.Scanner;public class RussiaPutBaby1 {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        int n=sc.nextInt();        int[] wide=new int[n];        int[] high=new int[n];        for(int i=0;i<n;i++){            wide[i]=sc.nextInt();            high[i]=sc.nextInt();        }        System.out.println(Solution(n, wide, high));    }    static int Solution(int n,int[] wide,int[] high){//n^2        int max=0;//记录嵌套的最大值        int levels;//以某一个为基础的情况下套下的层数        for(int i=0;i<n;i++){            levels=0;            //以一个套娃为基础,算算有多少能被他嵌套的(这里貌似是有问题的,重点看下一种方法)            for(int j=0;j<n;j++){                if(wide[i]>wide[j] && high[i]>high[j])                    levels++;            }            max=max>levels?max:levels;        }        return max;    }}

就是暴力算法,空间复杂度为O(1)(不算读取数据的数组)。时间复杂度:O(n*n)。

第二种:
先用宽进行排序,再对高求LIS。

import java.util.Scanner;public class RussiaPutBaby2 {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        int n=sc.nextInt();        int[] wide=new int[n];        int[] high=new int[n];        int w;        int h;        int index;        for(int i=0;i<n;i++){            index=i;            w=sc.nextInt();            h=sc.nextInt();            while(index!=0 && w<wide[index-1]){//插入排序                wide[index]=wide[index-1];                high[index]=high[index-1];                index--;            }            wide[index]=w;            high[index]=h;        }        System.out.println(Solution(n, high));    }    //LIS算法    public static int Solution(int n,int[] high) {        int max;        int ans = 0;        for (int i = 1; i < n; i++) {            max = 0;            for (int j = ans; j >= 0; j--) {                if (high[i] > high[j]) {                    max = j + 1;                    ans=ans>max?ans:max;                    break;                }            }            if( max==ans || high[i]<high[max])                high[max]=high[i];        }        return ans+1;    }}

我才用插入排序,因为在这题里,写起来很快,可以利用读数的过程。我估计这个方法的空间复杂度:O(1),时间复杂度:O(nlogn)(2为底)。不会算,只能估计了。

0 0