力扣118杨辉三角:代码实现+注释详解+其它思考

简介: 力扣118杨辉三角:代码实现+注释详解+其它思考

第一部分:题目

🏠 链接:118. 杨辉三角 - 力扣(LeetCode)

⭐ 难度:简单

第二部分:代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class PascalTriangle {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int numRows = scanner.nextInt();
        List<List<Integer>> lists = generate(numRows);
        System.out.println(lists);
        scanner.close();
    }
    public static List<List<Integer>> generate(int numRows) {
        List<List<Integer>> lists = new ArrayList<>();
        for (int i =0;i<numRows;i++){
            Integer[] array = new Integer[i + 1];
            array[0]=1;
            array[i]=1;
            for (int j = 1;j<=i/2;j++){
                array[j]=lists.get(i-1).get(j)+lists.get(i-1).get(j-1);
                array[i-j] = array[j];
            }
            lists.add(Arrays.asList(array));
        }
        return lists;
    }
}

第三部分:题解

3.1 generate()方法解析

public static List<List<Integer>> generate(int numRows) {
    List<List<Integer>> lists = new ArrayList<>();//设置List<Integer>类型的List接口子类对象存储杨辉三角
    for (int i =0;i<numRows;i++){//对杨辉三角的第(i+1)层进行存储
        Integer[] array = new Integer[i + 1];//建立一个length=i+1的数组保存该层杨辉三角值
        array[0]=1;//该层第一个元素值设置为1
        array[i]=1;//该层最后一个元素值设置为1
        for (int j = 1;j<=i/2;j++){
            //从第2个元素开始设置索引在[1,i-1]的元素,但由于每一层的对称性,所以只需要遍历一半(i/2)即可
            array[j]=lists.get(i-1).get(j)+lists.get(i-1).get(j-1);//得到上一层的list并取到对应索引赋值
            array[i-j] = array[j];//由对称性进行赋值,对称的两个索引的和为i
        }
        lists.add(Arrays.asList(array));//将该层的元素值由array->list形式存储到lists集合
    }
    return lists;//返回杨辉三角
}

3.2 main方法调用

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);//创建一个扫描器
    int numRows = scanner.nextInt();//键盘输入得到numRows
    List<List<Integer>> lists = generate(numRows);//得到杨辉三角
    System.out.println(lists);//隐式调用重写的toString方法显示杨辉三角
    scanner.close();//关闭扫描器,释放资源
}

第四部分:思考

Integer[] array = new Integer[i + 1];
array[0]=1;
array[i]=1;
for (int j = 1;j<=i/2;j++){
    array[j]=lists.get(i-1).get(j)+lists.get(i-1).get(j-1);
    array[i-j] = array[j];
}
lists.add(Arrays.asList(array));

对于generate()方法的这一部分,最初的写法是如下

for (int i =0;i<numRows;i++){
    List<Integer> list = new ArrayList<>();
    list.set(0,1);//该处抛出异常
    list.set(i,1);
    for (int j = 1;j<=i/2;j++){
        list.set(j,lists.get(i-1).get(j)+lists.get(i-1).get(j-1));
        list.set(i-j,list.get(j));
    }
    lists.add(list);
}

即是每层直接创建ArrayList对象,将元素值通过set(Index,Element element)方法设置,但测试发现在刚开始的第三行就抛出了IndexOutOfBoundsException,于是进行debug发现

也就是说,set方法调用的前提条件是该索引位置已经设置过了元素值,否则是无法设置的,会抛出异常

你可能有疑惑为什么不用add方法代替set方法,是因为我用了对称的方法减少遍历次数,如果用add会很麻烦,你可以试试。当然,这种对称的方法效率可能比起全部遍历不会高,因为存在需要将array->list的过程,还是会把该层的全部元素遍历。


相关文章
|
3月前
代码随想录 Day46 动态规划14 LeetCode T392 判断子序列 T115 不同的子序列
代码随想录 Day46 动态规划14 LeetCode T392 判断子序列 T115 不同的子序列
38 0
|
3月前
代码随想录Day33 LeetCode T62不同路径 LeetCode T63 不同路径II
代码随想录Day33 LeetCode T62不同路径 LeetCode T63 不同路径II
47 0
|
9天前
|
算法
代码随想录算法训练营第六十天 | LeetCode 84. 柱状图中最大的矩形
代码随想录算法训练营第六十天 | LeetCode 84. 柱状图中最大的矩形
18 3
|
9天前
|
算法
代码随想录算法训练营第五十七天 | LeetCode 739. 每日温度、496. 下一个更大元素 I
代码随想录算法训练营第五十七天 | LeetCode 739. 每日温度、496. 下一个更大元素 I
14 3
|
9天前
|
算法
代码随想录算法训练营第五十六天 | LeetCode 647. 回文子串、516. 最长回文子序列、动态规划总结
代码随想录算法训练营第五十六天 | LeetCode 647. 回文子串、516. 最长回文子序列、动态规划总结
30 1
|
3月前
代码随想录Day51 完结篇 LeetCode T84 柱状图的最大矩形
代码随想录Day51 完结篇 LeetCode T84 柱状图的最大矩形
19 0
|
3月前
|
容器
代码随想录 Day49 单调栈01 LeetCode LeetCodeT739每日温度 T496 下一个最大元素I
代码随想录 Day49 单调栈01 LeetCode LeetCodeT739每日温度 T496 下一个最大元素I
32 0
|
3月前
代码随想录 Day47 动态规划15 LeetCode T583 两个字符串的删除操作 T72 编辑距离
代码随想录 Day47 动态规划15 LeetCode T583 两个字符串的删除操作 T72 编辑距离
35 0
|
3月前
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
38 0
|
3月前
代码随想录 Day44 动规12 LeetCode T300 最长递增子序列 T674 最长连续递增序列 T718 最长重复子数组
代码随想录 Day44 动规12 LeetCode T300 最长递增子序列 T674 最长连续递增序列 T718 最长重复子数组
43 0