java递归输出杨辉三角,杨辉三角算法 | zhangman523

杨辉三角 的算法实现

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

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

02ed5afe5dbecdccd9d1c83b258a0f1e.gif

基本情况

可以看到,每行的最左边和最右边的数字是基本情况,在这个问题中,它总是等于 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]

]

1

2

3

4

5

6

7

8

9

10

11

输入:5

输出:

[

[1],

[1,1],

[1,2,1],

[1,3,3,1],

[1,4,6,4,1]

]

方法一 迭代实现

public List generateTrangle(int numRows){

List> list = new ArrayList<>();

for(int i=0;i

List subList = new ArrayList<>();

list.add(subList);

for(int j=0;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;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

publicListgenerateTrangle(intnumRows){

List>list=newArrayList<>();

for(inti=0;i

ListsubList=newArrayList<>();

list.add(subList);

for(intj=0;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)));

}

}

}

returnlist;

}

方法二 递归实现

public List> generateTriangleByRecursive(int numRow) {

List> list = new ArrayList<>();

for (int i = 0; i < numRow; i++) {

List 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;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

publicList>generateTriangleByRecursive(intnumRow){

List>list=newArrayList<>();

for(inti=0;i

ListsubList=newArrayList<>();

for(intj=0;j

subList.add(generate_Triangle_by_recursive(i,j));

}

list.add(subList);

}

returnlist;

}

privateintgenerate_Triangle_by_recursive(inti,intj){

intresult;

if(j==0||j==i){

result=1;

}else{

result=

(generate_Triangle_by_recursive(i-1,j-1)+generate_Triangle_by_recursive(

i-1,j));

}

returnresult;

}

在上面的例子中,您可能已经注意到递归解决方案可能会导致一些重复的计算,例如,我们重复计算相同的中间数以获得最后一行中的数字。 举例说明,为了得到 f(5, 3) 的结果,我们在 f(4, 2) 和 f(4, 3) 的调用中计算了 f(3, 2) 两次。下面我们优化递归算法

方法三 递归+记忆化

public List> generateTriangleByRecursive(int numRow) {

List> list = new ArrayList<>();

Map> cacheMap = new HashMap<>();

for (int i = 0; i < numRow; i++) {

List 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> 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 map = new HashMap<>();

cacheMap.put(i, map);

}

cacheMap.get(i).put(j, result);

return result;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

publicList>generateTriangleByRecursive(intnumRow){

List>list=newArrayList<>();

Map>cacheMap=newHashMap<>();

for(inti=0;i

ListsubList=newArrayList<>();

for(intj=0;j

subList.add(generate_Triangle_by_recursive(i,j,cacheMap));

}

list.add(subList);

}

returnlist;

}

privateintgenerate_Triangle_by_recursive(inti,intj,

Map>cacheMap){

if(cacheMap.containsKey(i)&&cacheMap.get(i).containsKey(j)){

returncacheMap.get(i).get(j);

}

intresult;

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)){

Mapmap=newHashMap<>();

cacheMap.put(i,map);

}

cacheMap.get(i).put(j,result);

returnresult;

}

拓展算法

给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。

示例:

输入: 3

输出: [1,3,3,1]

1

2

3

4

输入:3

输出:[1,3,3,1]

public List getRow(int rowIndex) {

List> list = new ArrayList<>();

for(int i=0;i

List subList = new ArrayList<>();

list.add(subList);

for(int j=0;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);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

publicListgetRow(introwIndex){

List>list=newArrayList<>();

for(inti=0;i

ListsubList=newArrayList<>();

list.add(subList);

for(intj=0;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)));

}

}

}

returnlist.get(rowIndex);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值