【Leetcode題】119. 帕斯卡三角形 II

給定一個索引 k,返回帕斯卡三角形(楊輝三角)的第 k 行。

例如:

給定 k = 3,則返回 [1, 3, 3, 1]

你可以優(yōu)化你的算法到 O(k) 的空間復雜度嗎?

使用遞歸的方式: Ck[n] = Ck-1[n-1] + Ck-1[n]【超時了】

class Solution {
    public List<Integer> getRow(int rowIndex) {
        List<Integer> result = new ArrayList<Integer>(rowIndex+1);
        int half = rowIndex / 2;
        if(rowIndex == 1){
            result.add(1);
            result.add(1);
            return result;
        }
        
        for(int i=0;i<rowIndex + 1;i++){
            //如果是另一半,則取對稱元素
            if(i > half) {
                result.add(result.get(rowIndex - i));
            }
            else{
                result.add(getNum(rowIndex, i));
            }
        }
        return result;
    }
    //索引k, 第n個
    private Integer getNum(int k, int n) {
        if(k == 0 || k == 1){
            return 1;
        }
        if(n == 0 || n == k) {![WX20180331-204230.png](https://upload-images.jianshu.io/upload_images/3017321-424fcdc89cf783f0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

            return 1;
        }
        return getNum(k-1, n-1) + getNum(k-1, n);
    }
}

以上之所以出現(xiàn)超時,是因為遞歸調用時存在多次重復調用。

比如在計算getNum(10, 3)時會發(fā)起調用:

遞歸.png

如上圖所示,getNum(8,2),getNum(7,1)和getNum(7,2)會調用多次,越到后面,重復調用的遞歸會更多,如果把這些遞歸調用的結果保存下來,效果會不會更好呢?

class Solution {
    private Map<String,Integer> cache = new HashMap<String, Integer>();
    public List<Integer> getRow(int rowIndex) {
        List<Integer> result = new ArrayList<Integer>(rowIndex+1);
        int half = rowIndex / 2;
        if(rowIndex == 1){
            result.add(1);
            result.add(1);
            return result;
        }
        
        for(int i=0;i<rowIndex + 1;i++){
            //如果是另一半,則取對稱元素
            if(i > half) {
                result.add(result.get(rowIndex - i));
            }
            else{
                result.add(getNum(rowIndex, i));
            }
        }//0 1 2 3 1
        
        return result;
    }
    //索引k, 第n個
    private Integer getNum(int k, int n) {
        if(cache.get(k + ":" + n) != null){
            return cache.get(k + ":" + n);
        }
        if(k == 0 || k == 1){
            return 1;
        }
        if(n == 0 || n == k) {
            return 1;
        }
        int r = getNum(k-1, n-1) + getNum(k-1, n);
        cache.put(k + ":" + n, r);
        return r;
    }

}

結果很nice, Leetcode給的結論是【4ms】,然而這個結果卻是所有答案中耗時最大的,難道還有優(yōu)化的地步。

楊輝三角規(guī)律:

第n行第1個數(shù): 1
第n行第2個數(shù):1×(n-1)
第n行第3個數(shù):1×(n-1)×(n-2)/2
第n行第4個數(shù):   1×(n-1)×(n-2)/2*(n-3)/3

用索引講:

第k索引行第0索引數(shù):1
第k索引行第1索引數(shù):1×k
第k索引行第2索引數(shù):1×k×(k-1)/2
第k索引行第3索引數(shù):1×k×(k-1)/2×(k-2)/3

所以最終答案: 【耗時1ms】

class Solution {
    public List<Integer> getRow(int rowIndex) {
        List<Integer> result = new ArrayList<Integer>(rowIndex+1);
        int half = rowIndex / 2;
        if(rowIndex == 1){
            result.add(1);
            result.add(1);
            return result;
        }
        
        for(int i=0;i<rowIndex + 1;i++){
            if(i == 0){
                result.add(1);
                continue;
            }
            //如果是另一半,則取對稱元素
            if(i > half) {
                result.add(result.get(rowIndex - i));
            }
            else{
                result.add(Double.valueOf(1.0 * result.get(i-1) * (rowIndex - (i-1)) / i).intValue());
            }
        }//0 1 2 3 1
        
        return result;
    }
}

總結: 楊輝三角每行元素不僅和上一行有關系,同一行元素之間的關系也頗為密切。而遞歸則是采用第一種方案,不用緩存在計算大數(shù)時會出現(xiàn)超時,而第二種方案則非常輕松實現(xiàn)。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 這個不錯分享給大家,從扣上看到的,就轉過來了 《電腦專業(yè)英語》 file [fail] n. 文件;v. 保存文...
    麥子先生R閱讀 7,117評論 5 24
  • 50道經典Java編程練習題,將數(shù)學思維運用到編程中來。抱歉哈找不到文章的原貼了,有冒犯的麻煩知會聲哈~ 1.指數(shù)...
    OSET我要編程閱讀 7,289評論 0 9
  • 下過雨的樹葉 總是那么鮮活 那停留在樹葉上的雨滴 透明的可以看到葉脈的紋路 下過雨后 空氣都這么干凈 給人一種清爽
    李欣芮_北斗閱讀 222評論 0 0
  • 謁荊州關廟贈諸君 洪波作品 桃園結義百代師,三顧茅廬為侍從。 鳳眼蠶眉忠義士,偃月赤兔美髯公。 十里旌旗蔽白日,...
    洪波shenhb8939153閱讀 630評論 2 2
  • 其一 平沙征戰(zhàn)三載, 樓蘭劍破未還。 出塞纏頭男兒, 歸來青骨白發(fā)。 哀哉,哀哉! 權貴低迷尋樂, 料想戍邊人, ...
    天空依舊perfect閱讀 163評論 0 1

友情鏈接更多精彩內容