楊輝三角 的算法實現

原文www.zhangman523.cn/420.htmlhtml

楊輝三角 的算法實現

楊輝三角形是排列成三角形的一系列數字。 在楊輝三角形中,每一行的最左邊和最右邊的數字老是 1。 對於其他的每一個數字都是前一行中直接位於它上面的兩個數字之和。java

下面給出一個5行的楊輝三角:算法

yanghuiTrangle

基本狀況

能夠看到,每行的最左邊和最右邊的數字是基本狀況,在這個問題中,它老是等於 1。 所以,咱們能夠將基本狀況定義以下:bash

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

遞推關係

讓咱們從楊輝三角形內的遞推關係開始。 首先,咱們定義一個函數 f(i, j)它將會返回楊輝三角形第 i 行、第 j 列的數字。優化

咱們能夠用下面的公式來表示這一遞推關係:ui

f(i,j)=f(i−1,j−1)+f(i−1,j)spa

java 實現

給定一個非負整數 numRows,生成楊輝三角的前 numRows 行。code

示例:cdn

輸入: 5
輸出:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]
複製代碼

方法一 迭代實現


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){//每行的最左邊和最右邊的數字都是1
                subList.add(1);
            }else{
                //遞推關係
                subList.add((list.get(i-1).get(j-1)+list.get(i-1).get(j)));
            }
        }
    }
    return list;
}
複製代碼

方法二 遞歸實現


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;
  }
複製代碼

在上面的例子中,您可能已經注意到遞歸解決方案可能會致使一些重複的計算,例如,咱們重複計算相同的中間數以得到最後一行中的數字。 舉例說明,爲了獲得 f(5, 3) 的結果,咱們在 f(4, 2) 和 f(4, 3) 的調用中計算了 f(3, 2) 兩次。下面咱們優化遞歸算法

方法三 遞歸+記憶化


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;
  }
複製代碼

拓展算法


給定一個非負索引 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);
}
複製代碼
相關文章
相關標籤/搜索