【透过算法了解编程】之杨辉三角

本文通过一个简单的杨辉三角问题,解析算法的奥秘与编程的乐趣。阐述了如何处理固定元素和计算元素,选择了ArrayList作为数据结构,并提供了详细的代码实现,讲解了时间复杂度和空间复杂度,帮助理解算法的「大道至简」。
摘要由CSDN通过智能技术生成

Hello,大家好。夜深人静宿自宽,不羡鸳鸯不羡仙!我是猿码。

前几日与同事聊起算法,他说算法很难,从来没有接触过。而在我看来,算法已经不在那么神秘,她真正妖娆的地方是无穷的规律与精简。我们中国有句古话叫“大道至简,大悟无言”,前半句用来形容算法真的很贴切,但是后半句可以用来形容领悟了算法背后规律的心情。

恩,话不多说了,我们开始探索算法背后编程乐趣的真正细节吧!

🔍 题目:给一个数字n, (0 <= n <= 30),请构建一个杨辉三角。

📕 题目介绍

杨辉三角相关定义:

  • 杨辉三角是由 n 行数量不同的数列组成,由于规律排列后形似三角形,且为古代数学家杨辉或贾宪所发现,因此叫杨辉或贾宪三角
  • 规律排列后,该几何具有对称性,且三角形左右两边的数字都是 1
  • i 行第 j 列元素为 i - 1 行 第 j - 1 列与第 j 列元素之和
  • n >= 2 时,设每行的数字数量为 k,数列为 arr,则有 arr[1] = narr[k-2] = n
  • n >= 0i > 0 时,则有 arr[i] = arr[i - 1] * (n - i + 1) / i

难度:容易 (Easy)

题目来源:力扣(LeetCode)  

 💡 题目分析

具体公式,已经在定义中列举出来了,可以结合 Gif 图来分析其原理。

这道题由于每行的数字列数呈递增趋势,且行数编号与列数相等,其中行数从 1 开始。因此,在选择数据结构上,我们优先考虑可变数组 ArrayList。

这道题唯一需要注意的地方是:对于三角中固定值与被计算出来的值的处理方式。固定值,分布在行的两端,这两个值可以直接在循环中手动添加到子集合当中即可。被计算出来的值,在不使用公式的前提下,是需要去 List[i - 1] 中去取,然后进行计算得出。因此我们需要在原有的循环内部,再创建一个从 2 开始,i - 1 结束的内循环。

🖊 代码实现

    public List<List<Integer>> generate(int numRows) {
        // 父集合
        List<List<Integer>> ans = new ArrayList<>();
        // 子集合
        List<Integer> row = new ArrayList<>();
        // 手动添加第 1 行
        row.add(1); ans.add(row);
        for (int i = 1; i < numRows; i++) {
            // 子集合
            row = new ArrayList<>(i + 1);
            // 添加固定值 1 
            row.add(1);
            // 当 i > 1 时,第 2 个数字与第 numRows - 2
            // 个数字与当前行数对应,可以直接添加,无需计算
            if(i > 1) row.add(i);
            if(i > 3) {
                // 当 i > 3 时再去遍历父集合计算当前集合需要的元素
                for(int j = 2; j <= i - 2; j++) {
                    row.add(ans.get(i - 1).get(j - 1) + ans.get(i - 1).get(j));
                }
            }
            // 第 numRows - 2 个数字与行数对应无需计算
            if(i > 2) row.add(i);
            row.add(1);
            ans.add(row);
        }
        return ans;
    }

时间复杂度:O(n^{2})n 为三角的总行数,去掉常数和低阶项

空间复杂度:O(n^{2})这里包括返回值的占用空间

📕总结

学习点:

  • 如何处理固定元素与被计算出来的元素
  • 如何选择一个合适的数据结构处理数据
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿码叔叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值