俄羅斯套娃問題(Java)

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章