杨辉三角 的算法实现

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

杨辉三角 的算法实现

杨辉三角形是排列成三角形的一系列数字。 在杨辉三角形中,每一行的最左边和最右边的数字总是 1。 对于其余的每个数字都是前一行中直接位于它上面的两个数字之和。

下面给出一个5行的杨辉三角:

yanghuiTrangle

基本情况

可以看到,每行的最左边和最右边的数字是基本情况,在这个问题中,它总是等于 1。
因此,我们可以将基本情况定义如下:

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

递推关系

让我们从杨辉三角形内的递推关系开始。
首先,我们定义一个函数 f(i, j)它将会返回杨辉三角形第 i 行、第 j 列的数字。

我们可以用下面的公式来表示这一递推关系:

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

java 实现

给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。

示例:

输入: 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);
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,426评论 0 2
  • 【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔...
    开心的锣鼓阅读 3,353评论 0 9
  • Java经典问题算法大全 /*【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子...
    赵宇_阿特奇阅读 1,925评论 0 2
  • 50道经典Java编程练习题,将数学思维运用到编程中来。抱歉哈找不到文章的原贴了,有冒犯的麻烦知会声哈~ 1.指数...
    OSET我要编程阅读 7,190评论 0 9
  • 一年级语文上册生字表 生字表一(共400字) 啊(ā)爱(ài)安(ān)岸(àn)爸(bà)八(bā)巴(bā)...
    meychang阅读 2,900评论 0 6