问题,输入:第一行 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为底)。不会算,只能估计了。