問題,輸入:第一行 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爲底)。不會算,只能估計了。