楊輝三角 的算法實(shí)現(xiàn)

原文https://www.zhangman523.cn/420.html

楊輝三角 的算法實(shí)現(xiàn)

楊輝三角形是排列成三角形的一系列數(shù)字。 在楊輝三角形中,每一行的最左邊和最右邊的數(shù)字總是 1。 對于其余的每個(gè)數(shù)字都是前一行中直接位于它上面的兩個(gè)數(shù)字之和。

下面給出一個(gè)5行的楊輝三角:

yanghuiTrangle

基本情況

可以看到,每行的最左邊和最右邊的數(shù)字是基本情況,在這個(gè)問題中,它總是等于 1。
因此,我們可以將基本情況定義如下:

f(i,j) = 1 where j=1 or j=i

遞推關(guān)系

讓我們從楊輝三角形內(nèi)的遞推關(guān)系開始。
首先,我們定義一個(gè)函數(shù) f(i, j)它將會(huì)返回楊輝三角形第 i 行、第 j 列的數(shù)字。

我們可以用下面的公式來表示這一遞推關(guān)系:

f(i,j)=f(i?1,j?1)+f(i?1,j)

java 實(shí)現(xiàn)

給定一個(gè)非負(fù)整數(shù) numRows,生成楊輝三角的前 numRows 行。

示例:

輸入: 5
輸出:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]

方法一 迭代實(shí)現(xiàn)


public List<List<Integer> generateTrangle(int numRows){
    List<List<Integer>> list = new ArrayList<>();
    for(int i=0;i<numRows;i++){
        List<Integer> subList = new ArrayList<>();
        list.add(subList);
        for(int j=0;j<i+1;j++){
            f(j==i||j==0){//每行的最左邊和最右邊的數(shù)字都是1
                subList.add(1);
            }else{
                //遞推關(guān)系
                subList.add((list.get(i-1).get(j-1)+list.get(i-1).get(j)));
            }
        }
    }
    return list;
}

方法二 遞歸實(shí)現(xiàn)


public List<List<Integer>> generateTriangleByRecursive(int numRow) {
    List<List<Integer>> list = new ArrayList<>();
    for (int i = 0; i < numRow; i++) {
      List<Integer> subList = new ArrayList<>();
      for (int j = 0; j < i + 1; j++) {
        subList.add(generate_Triangle_by_recursive(i, j));
      }
      list.add(subList);
    }
    return list;
}

private int generate_Triangle_by_recursive(int i, int j) {
    int result;
    if (j == 0 || j == i) {
      result = 1;
    } else {
      result =
          (generate_Triangle_by_recursive(i - 1, j - 1) + generate_Triangle_by_recursive(
              i - 1, j));
    }
    return result;
  }

在上面的例子中,您可能已經(jīng)注意到遞歸解決方案可能會(huì)導(dǎo)致一些重復(fù)的計(jì)算,例如,我們重復(fù)計(jì)算相同的中間數(shù)以獲得最后一行中的數(shù)字。 舉例說明,為了得到 f(5, 3) 的結(jié)果,我們在 f(4, 2) 和 f(4, 3) 的調(diào)用中計(jì)算了 f(3, 2) 兩次。下面我們優(yōu)化遞歸算法

方法三 遞歸+記憶化


 public List<List<Integer>> generateTriangleByRecursive(int numRow) {
    List<List<Integer>> list = new ArrayList<>();
    Map<Integer, Map<Integer, Integer>> cacheMap = new HashMap<>();
    for (int i = 0; i < numRow; i++) {
      List<Integer> subList = new ArrayList<>();
      for (int j = 0; j < i + 1; j++) {
        subList.add(generate_Triangle_by_recursive(i, j, cacheMap));
      }
      list.add(subList);
    }
    return list;
  }

  private int generate_Triangle_by_recursive(int i, int j,
      Map<Integer, Map<Integer, Integer>> cacheMap) {
    if (cacheMap.containsKey(i) && cacheMap.get(i).containsKey(j)) {
      return cacheMap.get(i).get(j);
    }
    int result;
    if (j == 0 || j == i) {
      result = 1;
    } else {
      result =
          (generate_Triangle_by_recursive(i - 1, j - 1, cacheMap) + generate_Triangle_by_recursive(
              i - 1, j, cacheMap));
    }
    if (!cacheMap.containsKey(i)) {
      Map<Integer, Integer> map = new HashMap<>();
      cacheMap.put(i, map);
    }
    cacheMap.get(i).put(j, result);
    return result;
  }

拓展算法


給定一個(gè)非負(fù)索引 k,其中 k ≤ 33,返回楊輝三角的第 k 行。

示例:

輸入: 3
輸出: [1,3,3,1]
public List<Integer> getRow(int rowIndex) {
    List<List<Integer>> list = new ArrayList<>();
        for(int i=0;i<rowIndex+1;i++){
            List<Integer> subList = new ArrayList<>();
            list.add(subList);
            for(int j=0;j<i+1;j++){
                if(j==i||j==0){//first and end 
                    subList.add(1);
                }else{
                   subList.add((list.get(i-1).get(j-1)+list.get(i-1).get(j)));
                }
            }
        }
    return list.get(rowIndex);
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在C語言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 4,053評論 0 2
  • 【程序1】 題目:古典問題:有一對兔子,從出生后第3個(gè)月起每個(gè)月都生一對兔子,小兔子長到第三個(gè)月后每個(gè)月又生一對兔...
    開心的鑼鼓閱讀 3,395評論 0 9
  • Java經(jīng)典問題算法大全 /*【程序1】 題目:古典問題:有一對兔子,從出生后第3個(gè)月起每個(gè)月都生一對兔子,小兔子...
    趙宇_阿特奇閱讀 2,082評論 0 2
  • 50道經(jīng)典Java編程練習(xí)題,將數(shù)學(xué)思維運(yùn)用到編程中來。抱歉哈找不到文章的原貼了,有冒犯的麻煩知會(huì)聲哈~ 1.指數(shù)...
    OSET我要編程閱讀 7,289評論 0 9
  • 一年級語文上冊生字表 生字表一(共400字) 啊(ā)愛(ài)安(ān)岸(àn)爸(bà)八(bā)巴(bā)...
    meychang閱讀 3,155評論 0 6

友情鏈接更多精彩內(nèi)容