【LeetCode】279完全平方數

 

思路:動態規劃,最初想到的公式是:

後來提交之後報出超時錯誤,因此參考了題解,找到正確的公式爲:

第二個公式直接計算“前段”爲平方數的情況,比起第一個公式,時間複雜度從n^2降低到n^1.5;

因此,僅僅寫出動態規劃的公式是不夠的,需要保證:

(1)公式的正確性;

(2)公式的高效性,此一條跟題目有關。

詳細分析題目中可以用來降低時間複雜度的題點,喫一塹長一智~。

代碼1. 循環寫法:

    public int numSquares(int n){
        if(n<=0) return 0;
        int[] fn=new int[n+1];
        fn[0]=0;
        fn[1]=1;

        //填充數組的過程
        for(int i=2;i<n+1;i++){
            int min=i;
            for(int j=1;j*j<=i;j++){
                if(min>1+fn[i-j*j]) {
                    min = 1 + fn[i - j * j];
                }
            }
            fn[i]=min;
        }

        return fn[n];
    }

代碼2. 遞歸寫法:

    public static int numSquares(int n) {
        if(n<=0) return 0;
        int[] fn=new int[n+1];
        fn[0]=0;
        fn[1]=1;
        //開始遞歸
        numSquaresCore(n,fn);
        //獲得結果
        int answer=fn[n];
        return answer;
    }

    public static int numSquaresCore(int index,int[] fn){
        //解決已知情況
        if(index<=0) return 0;
        if(index==1) return 1;
        if(fn[index]!=0) return fn[index];

        //最大不會超過index個,就是index=1+1+...+1的情況
        int min=index;
        int border=(int)(Math.pow(index,0.5)+0.5);
        for(int i=1;i<=border;i++){
            if(index-i*i==0){
                //當前爲平方數
                min=1;
            }
            else if(index-i*i>0){
                //減掉i*i,然後計算剩餘的子問題
                if(fn[index-i*i]==0){
                    fn[index-i*i]=numSquaresCore(index-i*i,fn);
                }
                if(min>1+fn[index-i*i]){
                    min=1+fn[index-i*i];
                }
            }
        }

        fn[index]=min;
        return min;
    }

 

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