在C语言的入门课程中,通常会介绍杨辉三角这一个问题,解决的办法是利用二维数组递推公式。其中C语言实现并不难,因为可以申请多余的空间,充分利用数字0,来避开边界条件。这也是初学者经常使用的方式。
对于杨辉三角问题,实际上是一个简单的动态规划问题。基本的表述有让你求出所有的杨辉三角以及让你求出指定行数的杨辉三角。
对于求出所有的杨辉三角,那么就是二维数组存储。这时不用对动态规划递推公式进行优化。下面给出Java List实现
public class solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> res = new ArrayList<>();
if(numRows==0) return res;
res.add(new ArrayList<>());
res.get(0).add(1);
for(int i=1;i<numRows;i++){
List<Integer> rows = new ArrayList<>();
List<Integer> prevRow = res.get(i-1);
rows.add(1);
for(int j=1;j<i;j++){
rows.add(prevRow.get(j-1)+prevRow.get(j));
}
rows.add(1);
res.add(rows);
}
return res;
}
}
如果要求只打印一行,不要存下所有的杨辉三角,那么可以用一维数组实现,最自然的思路就是滚动数组
class Solution {
public List<Integer> getRow(int rowIndex) {
List<Integer> cur = new ArrayList<>();
cur.add(1);
if(rowIndex==0) return cur;
List<Integer> pre = new ArrayList<>();
for(int i=1;i<=rowIndex;i++){
cur = new ArrayList<>();
cur.add(1);
for(int j=1;j<i;j++){
cur.add(pre.get(j-1)+pre.get(j));
}
cur.add(1);
pre = cur;
}
return cur;
}
}
这里要指出的是,这里滚动数组实际上需要不断delete掉之前的pre数组,由于Java有垃圾回收机制,不需要我们手动这么做。
所以严格来说,这个在Java中也相当于用了二维数组
纯粹的一维求解,是在原来数组的基础上,进行更新。(从后往前)
class Solution {
public List<Integer> getRow(int rowIndex) {
List<Integer> res = new ArrayList<Integer>();
for(int i = 0;i<rowIndex+1;i++) {
res.add(1);
for(int j=i-1;j>0;j--) {
res.set(j, res.get(j-1)+res.get(j));
}
}
return res;
}
}
注意:一般的面试题中,很少要求对DP的空间复杂度做优化。